Cataclysm BN
Character Class Referenceabstract

#include <character.h>

Inheritance diagram for Character:
Creature visitable< Character > player avatar npc standard_npc

Classes

struct  has_mission_item_filter
 

Public Types

enum  water_tolerance { WT_IGNORED = 0 , WT_NEUTRAL , WT_GOOD , NUM_WATER_TOLERANCE }
 
using trap_map = std::map< tripoint, std::string >
 
- Public Types inherited from Creature
enum  Attitude : int { A_HOSTILE , A_NEUTRAL , A_FRIENDLY , A_ANY }
 Simplified attitude towards any creature: hostile - hate, want to kill, etc. More...
 

Public Member Functions

 Character (const Character &)=delete
 
Characteroperator= (const Character &)=delete
 
 ~Character () override
 
Characteras_character () override
 
const Characteras_character () const override
 
character_id getID () const
 
void setID (character_id i, bool force=false)
 
bool is_dead_state () const override
 Returns true if the character should be dead. More...
 
field_type_id bloodType () const override
 
field_type_id gibType () const override
 
bool is_warm () const override
 
bool in_species (const species_id &spec) const override
 
const std::string & symbol () const override
 
virtual int get_str () const
 Getters for stats exclusive to characters. More...
 
virtual int get_dex () const
 
virtual int get_per () const
 
virtual int get_int () const
 
virtual int get_str_base () const
 
virtual int get_dex_base () const
 
virtual int get_per_base () const
 
virtual int get_int_base () const
 
virtual int get_str_bonus () const
 
virtual int get_dex_bonus () const
 
virtual int get_per_bonus () const
 
virtual int get_int_bonus () const
 
int get_speed () const override
 
virtual int ranged_dex_mod () const
 
virtual int ranged_per_mod () const
 
virtual void set_str_bonus (int nstr)
 Setters for stats exclusive to characters. More...
 
virtual void set_dex_bonus (int ndex)
 
virtual void set_per_bonus (int nper)
 
virtual void set_int_bonus (int nint)
 
virtual void mod_str_bonus (int nstr)
 
virtual void mod_dex_bonus (int ndex)
 
virtual void mod_per_bonus (int nper)
 
virtual void mod_int_bonus (int nint)
 
void print_health () const
 
virtual int get_healthy () const
 Getters for health values exclusive to characters. More...
 
virtual int get_healthy_mod () const
 
virtual void mod_healthy (int nhealthy)
 Modifiers for health values exclusive to characters. More...
 
virtual void mod_healthy_mod (int nhealthy_mod, int cap)
 
virtual void set_healthy (int nhealthy)
 Setters for health values exclusive to characters. More...
 
virtual void set_healthy_mod (int nhealthy_mod)
 
int get_stored_kcal () const
 Getter for need values exclusive to characters. More...
 
int max_stored_kcal () const
 
float get_kcal_percent () const
 
int get_thirst () const
 
std::pair< std::string, nc_colorget_thirst_description () const
 
std::pair< std::string, nc_colorget_hunger_description () const
 
std::pair< std::string, nc_colorget_fatigue_description () const
 
int get_fatigue () const
 
int get_sleep_deprivation () const
 
std::pair< std::string, nc_colorget_pain_description () const override
 
virtual void mod_stored_kcal (int nkcal)
 Modifiers for need values exclusive to characters. More...
 
virtual void mod_stored_nutr (int nnutr)
 
virtual void mod_thirst (int nthirst)
 
virtual void mod_fatigue (int nfatigue)
 
virtual void mod_sleep_deprivation (int nsleep_deprivation)
 
virtual void set_stored_kcal (int kcal)
 Setters for need values exclusive to characters. More...
 
virtual void set_thirst (int nthirst)
 
virtual void set_fatigue (int nfatigue)
 
virtual void set_sleep_deprivation (int nsleep_deprivation)
 
void mod_stat (const std::string &stat, float modifier) override
 
m_size get_size () const override
 Get size class of character. More...
 
void recalculate_size ()
 Recalculate size class of character. More...
 
void recalc_speed_bonus ()
 Calculates the various speed bonuses we will get from mutations, etc. More...
 
std::string disp_name (bool possessive=false, bool capitalize_first=false) const override
 Returns either "you" or the player's name. More...
 
std::string skin_name () const override
 Returns the name of the player's outer layer, e.g. More...
 
virtual factionget_faction () const
 
void set_fac_id (const std::string &my_fac_id)
 
float get_dodge_base () const override
 Combat getters. More...
 
float get_hit_base () const override
 
float get_dodge () const override
 
float dodge_roll () override
 
float get_melee () const override
 Returns melee skill level, to be used to throttle dodge practice. More...
 
const tripointpos () const override
 
int sight_range (int light_level) const override
 Returns the player's sight range. More...
 
int unimpaired_range () const
 Returns the player maximum vision range factoring in mutations, diseases, and other effects. More...
 
bool overmap_los (const tripoint_abs_omt &omt, int sight_points)
 Returns true if overmap tile is within player line-of-sight. More...
 
int overmap_sight_range (int light_level) const
 Returns the distance the player can see on the overmap. More...
 
int clairvoyance () const
 Returns the distance the player can see through walls. More...
 
bool sight_impaired () const
 Returns true if the player has some form of impaired sight. More...
 
bool has_alarm_clock () const
 Returns true if the player or their vehicle has an alarm clock. More...
 
bool has_watch () const
 Returns true if the player or their vehicle has a watch. More...
 
void action_taken ()
 Called after every action, invalidates player caches. More...
 
bool is_on_ground () const override
 Returns true if the player is knocked over or has broken legs. More...
 
int swim_speed () const
 Returns the player's speed for swimming across water tiles. More...
 
void add_miss_reason (const std::string &reason, unsigned int weight)
 Adds a reason for why the player would miss a melee attack. More...
 
void clear_miss_reasons ()
 Clears the list of reasons for why the player would miss a melee attack. More...
 
std::string get_miss_reason ()
 Returns an explanation for why the player would miss a melee attack. More...
 
void knock_back_to (const tripoint &to) override
 Knocks the character to a specified tile. More...
 
float fall_damage_mod () const override
 Returns multiplier on fall damage at low velocity (knockback/pit/1 z-level, not 5 z-levels) More...
 
int impact (int force, const tripoint &pos) override
 Deals falling/collision damage with terrain/creature at pos. More...
 
int hp_percentage () const override
 Returns overall % of HP remaining. More...
 
void regen (int rate_multiplier)
 Handles passive regeneration of pain and maybe hp. More...
 
void enforce_minimum_healing ()
 
itembest_quality_item (const quality_id &qual)
 get best quality item that this character has More...
 
virtual void update_health (int external_modifiers=0)
 Handles health fluctuations over time. More...
 
void update_body ()
 Updates all "biology" by one turn. More...
 
void update_body (const time_point &from, const time_point &to)
 Updates all "biology" as if time between from and to passed. More...
 
void update_stomach (const time_point &from, const time_point &to)
 Updates the stomach to give accurate hunger messages. More...
 
void update_needs (int rate_multiplier)
 Increases hunger, thirst, fatigue and stimulants wearing off. More...
 
needs_rates calc_needs_rates () const
 
void check_needs_extremes ()
 Kills the player if too hungry, stimmed up etc., forces tired player to sleep and prints warnings. More...
 
bool is_hibernating () const
 Returns if the player has hibernation mutation and is asleep and well fed. More...
 
void update_bodytemp (const map &m, const weather_manager &weather)
 Maintains body temperature. More...
 
void temp_equalizer (const bodypart_id &bp1, const bodypart_id &bp2)
 Equalizes heat between body parts. More...
 
int blood_loss (const bodypart_id &bp) const
 Define blood loss (in percents) More...
 
void reset_bonuses () override
 Resets the value of all bonus fields to 0. More...
 
void reset_stats () override
 Resets stats, and applies effects in an idempotent manner. More...
 
void reset () override
 Handles stat and bonus reset. More...
 
void environmental_revert_effect ()
 
void reset_encumbrance ()
 Recalculates encumbrance cache. More...
 
int encumb (body_part bp) const
 Returns ENC provided by armor, etc. More...
 
units::mass get_weight () const override
 Returns body weight plus weight of inventory and worn/wielded items. More...
 
char_encumbrance_data get_encumbrance () const
 Get encumbrance for all body parts. More...
 
char_encumbrance_data get_encumbrance (const item &new_item) const
 Get encumbrance for all body parts as if new_item was also worn. More...
 
int extraEncumbrance (layer_level level, int bp) const
 Get encumbrance penalty per layer & body part. More...
 
bool is_wearing_power_armor (bool *hasHelmet=nullptr) const
 Returns true if the character is wearing power armor. More...
 
bool is_wearing_active_power_armor () const
 Returns true if the character is wearing active power. More...
 
bool is_wearing_active_optcloak () const
 Returns true if the player is wearing an active optical cloak. More...
 
bool in_climate_control ()
 Returns true if the player is in a climate controlled area or armor. More...
 
bool is_blind () const
 Returns true if the player isn't able to see. More...
 
bool is_invisible () const
 
int visibility (bool check_color=false, int stillness=0) const
 Checks is_invisible() as well as other factors. More...
 
float active_light () const
 Returns character luminosity based on the brightest active item they are carrying. More...
 
bool sees_with_specials (const Creature &critter) const
 
body_part_set exclusive_flag_coverage (const std::string &flag) const
 Bitset of all the body parts covered only with items with flag (or nothing) More...
 
bool move_effects (bool attacking) override
 Processes effects which may prevent the Character from moving (bear traps, crushed, etc.). More...
 
void wait_effects ()
 
bool movement_mode_is (character_movemode mode) const
 Check against the character's current movement mode. More...
 
character_movemode get_movement_mode () const
 
virtual void set_movement_mode (character_movemode mode)=0
 
void expose_to_disease (diseasetype_id dis_type)
 Determine if character is susceptible to dis_type and if so apply the symptoms. More...
 
void process_turn () override
 Handles end-of-turn processing. More...
 
void process_effects_internal () override
 Processes human-specific effects of effects before calling Creature::process_effects(). More...
 
void hardcoded_effects (effect &it)
 Handles the still hard-coded effects. More...
 
void process_one_effect (effect &it, bool is_new) override
 Processes human-specific effects of an effect. More...
 
void process_items ()
 Process active items. More...
 
void recalc_hp ()
 Recalculates HP after a change to max strength. More...
 
void calc_all_parts_hp (float hp_mod=0.0, float hp_adjust=0.0, int str_max=0)
 Sets hp for all body parts. More...
 
void recalc_sight_limits ()
 Modifies the player's sight values Must be called when any of the following change: This must be called when any of the following change: More...
 
float get_vision_threshold (float light_level) const
 Returns the apparent light level at which the player can see. More...
 
void flag_encumbrance ()
 Flag encumbrance for updating. More...
 
void check_item_encumbrance_flag ()
 Checks worn items for the "RESET_ENCUMBRANCE" flag, which indicates that encumbrance may have changed and require recalculating. More...
 
bool natural_attack_restricted_on (const bodypart_id &bp) const
 Returns true if the character is wearing something on the entered body_part, ignoring items with the ALLOWS_NATURAL_ATTACKS flag. More...
 
bool can_use_grab_break_tec (const item &weap) const
 Returns true if the player is able to use a grab breaking technique. More...
 
bool can_miss_recovery (const item &weap) const
 Returns true if the player is able to use a miss recovery technique. More...
 
bool is_quiet () const
 Returns true if the player has quiet melee attacks. More...
 
bool is_stealthy () const
 Returns true if the player has stealthy movement. More...
 
bool uncanny_dodge () override
 Handles the uncanny dodge bionic and effects, returns true if the creature successfully dodges. More...
 
bool block_hit (Creature *source, bodypart_id &bp_hit, damage_instance &dam) override
 Checks for valid block abilities and reduces damage accordingly. More...
 
itembest_shield ()
 Returns the best item for blocking with. More...
 
bool handle_melee_wear (item &shield, float wear_multiplier=1.0f)
 Calculates melee weapon wear-and-tear through use, returns true if item is destroyed. More...
 
matec_id pick_technique (Creature &t, const item &weap, bool crit, bool dodge_counter, bool block_counter)
 Returns a random valid technique. More...
 
void perform_technique (const ma_technique &technique, Creature &t, damage_instance &di, int &move_cost)
 
void melee_attack (Creature &t, bool allow_special, const matec_id *force_technique=nullptr, bool allow_unarmed=true)
 Sets up a melee attack and handles melee attack function calls. More...
 
std::string melee_special_effects (Creature &t, damage_instance &d, item &weap)
 Handles combat effects, returns a string of any valid combat effect messages. More...
 
void perform_special_attacks (Creature &t, dealt_damage_instance &dealt_dam)
 Performs special attacks and their effects (poisonous, stinger, etc.) More...
 
void reach_attack (const tripoint &p)
 Handles reach melee attack on point p. More...
 
float stability_roll () const override
 Returns value of player's stable footing. More...
 
std::vector< special_attackmutation_attacks (Creature &t) const
 Returns a vector of valid mutation attacks. More...
 
float bonus_damage (bool random) const
 Returns the bonus bashing damage the player deals based on their stats. More...
 
float get_melee_hit_base () const
 Returns weapon skill. More...
 
float hit_roll () const override
 Returns the player's basic hit roll that is compared to the target's dodge roll. More...
 
double crit_chance (float roll_hit, float target_dodge, const item &weap) const
 Returns the chance to critical given a hit roll and target's dodge roll. More...
 
bool scored_crit (float target_dodge, const item &weap) const
 Returns true if the player scores a critical hit. More...
 
int attack_cost (const item &weap) const
 Returns cost (in moves) of attacking with given item (no modifiers, like stuck) More...
 
float get_hit_weapon (const item &weap) const
 Gets melee accuracy component from weapon+skills. More...
 
void roll_all_damage (bool crit, damage_instance &di, bool average, const item &weap) const
 Adds all 3 types of physical damage to instance. More...
 
void roll_bash_damage (bool crit, damage_instance &di, bool average, const item &weap) const
 Adds player's total bash damage to the damage instance. More...
 
void roll_cut_damage (bool crit, damage_instance &di, bool average, const item &weap) const
 Adds player's total cut damage to the damage instance. More...
 
void roll_stab_damage (bool crit, damage_instance &di, bool average, const item &weap) const
 Adds player's total stab damage to the damage instance. More...
 
void on_dodge (Creature *source, int difficulty) override
 This creature just dodged an attack - possibly special/ranged attack - from source. More...
 
void on_hit (Creature *source, bodypart_id bp_hit, dealt_projectile_attack const *proj) override
 This creature just got hit by an attack - possibly special/ranged attack - from source. More...
 
void did_hit (Creature &target)
 Handles special effects when the Character hits a Creature. More...
 
void apply_damage (Creature *source, bodypart_id hurt, int dam, bool bypass_med=false) override
 Actually hurt the player, hurts a body_part directly, no armor reduction. More...
 
dealt_damage_instance deal_damage (Creature *source, bodypart_id bp, const damage_instance &d) override
 Calls Creature::deal_damage and handles damaged effects (waking up, etc.) More...
 
int reduce_healing_effect (const efftype_id &eff_id, int remove_med, const bodypart_id &hurt)
 Reduce healing effect intensity, return initial intensity of the effect. More...
 
void cough (bool harmful=false, int loudness=4)
 
void passive_absorb_hit (const bodypart_id &bp, damage_unit &du) const
 Check for relevant passive, non-clothing that can absorb damage, and reduce by specified damage unit. More...
 
void absorb_hit (const bodypart_id &bp, damage_instance &dam) override
 Runs through all bionics and armor on a part and reduces damage through their armor_absorb. More...
 
bool armor_absorb (damage_unit &du, item &armor)
 Reduces and mutates du, prints messages about armor taking damage. More...
 
float bionic_armor_bonus (const bodypart_id &bp, damage_type dt) const
 Check for passive bionics that provide armor, and returns the armor bonus This is called from player::passive_absorb_hit. More...
 
int mabuff_armor_bonus (damage_type type) const
 Returns the armor bonus against given type from martial arts buffs. More...
 
std::map< bodypart_id, int > get_armor_fire (const std::map< bodypart_id, std::vector< const item * > > &clothing_map) const
 Returns overall fire resistance. More...
 
bool has_trait (const trait_id &b) const override
 Returns true if the player has the entered trait. More...
 
bool has_base_trait (const trait_id &b) const
 Returns true if the player has the entered starting trait. More...
 
bool has_trait_flag (const std::string &b) const
 Returns true if player has a trait with a flag. More...
 
bool has_opposite_trait (const trait_id &flag) const
 Returns true if character has a trait which cancels the entered trait. More...
 
void toggle_trait (const trait_id &)
 Toggles a trait on the player and in their mutation list. More...
 
void set_mutation (const trait_id &)
 Add or removes a mutation on the player, but does not trigger mutation loss/gain effects. More...
 
void unset_mutation (const trait_id &)
 
void switch_mutations (const trait_id &switched, const trait_id &target, bool start_powered)
 Unset switched mutation and set target mutation instead. More...
 
void activate_mutation (const trait_id &mutation)
 
void deactivate_mutation (const trait_id &mut)
 
void mutation_spend_resources (const trait_id &mut)
 Removes the appropriate costs (NOTE: will reapply mods & recalc sightlines in case of newly activated mutation). More...
 
bool can_mount (const monster &critter) const
 
void mount_creature (monster &z)
 
bool is_mounted () const
 
bool check_mount_will_move (const tripoint &dest_loc)
 
bool check_mount_is_spooked ()
 
void dismount ()
 
void forced_dismount ()
 
bool is_deaf () const
 
bool has_two_arms () const
 Returns true if the player has two functioning arms. More...
 
int get_working_arm_count () const
 Returns the number of functioning arms. More...
 
int get_working_leg_count () const
 Returns the number of functioning legs. More...
 
bool is_limb_disabled (const bodypart_id &limb) const
 Returns true if the limb is disabled(12.5% or less hp) More...
 
bool is_limb_hindered (hp_part limb) const
 Returns true if the limb is hindered(40% or less hp) More...
 
bool is_limb_broken (const bodypart_id &limb) const
 Returns true if the limb is broken. More...
 
bool can_run ()
 source of truth of whether a Character can run More...
 
void hurtall (int dam, Creature *source, bool disturb=true)
 Hurts all body parts for dam, no armor reduction. More...
 
int hitall (int dam, int vary, Creature *source)
 Harms all body parts for dam, with armor reduction. More...
 
void on_hurt (Creature *source, bool disturb=true)
 Handles effects that happen when the player is damaged and aware of the fact. More...
 
void heal (const bodypart_id &healed, int dam)
 Heals a body_part for dam. More...
 
void healall (int dam)
 Heals all body parts for dam. More...
 
hp_part body_window (const std::string &menu_header, bool show_all, bool precise, int normal_bonus, int head_bonus, int torso_bonus, float bleed, float bite, float infect, float bandage_power, float disinfectant_power) const
 Displays menu with body part hp, optionally with hp estimation after healing. More...
 
nc_color limb_color (const bodypart_id &bp, bool bleed, bool bite, bool infect) const
 
bool made_of (const material_id &m) const override
 
bool made_of_any (const std::set< material_id > &ms) const override
 
int posx () const override
 
int posy () const override
 
int posz () const override
 
void setx (int x)
 
void sety (int y)
 
void setz (int z)
 
void setpos (const tripoint &p) override
 
virtual tripoint global_square_location () const
 Global position, expressed in map square coordinate system (the most detailed coordinate system), used by the map. More...
 
tripoint global_sm_location () const
 Returns the location of the player in global submap coordinates. More...
 
tripoint_abs_omt global_omt_location () const
 Returns the location of the player in global overmap terrain coordinates. More...
 
void recalculate_enchantment_cache ()
 
void rebuild_mutation_cache ()
 
double bonus_from_enchantments (double base, enchant_vals::mod value, bool round=false) const
 Calculate bonus from enchantments for given base value. More...
 
bool has_mabuff (const mabuff_id &buff_id) const
 Returns true if the player has any martial arts buffs attached. More...
 
bool has_grab_break_tec () const override
 Returns true if the player has a grab breaking technique available. More...
 
float mabuff_tohit_bonus () const
 Returns the to hit bonus from martial arts buffs. More...
 
float mabuff_dodge_bonus () const
 Returns the dodge bonus from martial arts buffs. More...
 
int mabuff_block_bonus () const
 Returns the block bonus from martial arts buffs. More...
 
int mabuff_speed_bonus () const
 Returns the speed bonus from martial arts buffs. More...
 
int mabuff_arpen_bonus (damage_type type) const
 Returns the arpen bonus from martial arts buffs. More...
 
float mabuff_damage_mult (damage_type type) const
 Returns the damage multiplier to given type from martial arts buffs. More...
 
int mabuff_damage_bonus (damage_type type) const
 Returns the flat damage bonus to given type from martial arts buffs, applied after the multiplier. More...
 
int mabuff_attack_cost_penalty () const
 Returns the flat penalty to move cost of attacks. More...
 
float mabuff_attack_cost_mult () const
 Returns the multiplier on move cost of attacks. More...
 
void mutation_effect (const trait_id &mut)
 Handles things like removal of armor, etc. More...
 
void mutation_loss_effect (const trait_id &mut)
 Handles what happens when you lose a mutation. More...
 
bool has_active_mutation (const trait_id &b) const
 
void mutate ()
 Picks a random valid mutation and gives it to the Character, possibly removing/changing others along the way. More...
 
bool mutation_ok (const trait_id &mutation, bool force_good, bool force_bad) const
 Returns true if the player doesn't have the mutation or a conflicting one and it complies with the force typing. More...
 
void mutate_category (const std::string &mut_cat)
 Picks a random valid mutation in a category and mutate_towards() it. More...
 
bool mutate_towards (std::vector< trait_id > muts, int num_tries=INT_MAX)
 Mutates toward one of the given mutations, upgrading or removing conflicts if necessary. More...
 
bool mutate_towards (const trait_id &mut)
 Mutates toward the entered mutation, upgrading or removing conflicts if necessary. More...
 
void remove_mutation (const trait_id &mut, bool silent=false)
 Removes a mutation, downgrading to the previous level if possible. More...
 
std::map< trait_id, float > mutation_chances () const
 Calculate percentage chances for mutations. More...
 
bool has_child_flag (const trait_id &flag) const
 Returns true if the player has the entered mutation child flag. More...
 
void remove_child_flag (const trait_id &flag)
 Removes the mutation's child flag from the player's list. More...
 
void set_highest_cat_level ()
 Recalculates mutation_category_level[] values for the player. More...
 
std::string get_highest_category () const
 Returns the highest mutation category. More...
 
void drench_mut_calc ()
 Recalculates mutation drench protection for all bodyparts (ignored/good/neutral stats) More...
 
void build_mut_dependency_map (const trait_id &mut, std::unordered_map< trait_id, int > &dependency_map, int distance)
 Recursively traverses the mutation's prerequisites and replacements, building up a map. More...
 
bool is_category_allowed (const std::vector< std::string > &category) const
 Returns true if this category of mutation is allowed. More...
 
bool is_category_allowed (const std::string &category) const
 
bool is_weak_to_water () const
 
bool can_use_heal_item (const item &med) const
 Check for mutation disallowing the use of an healing item. More...
 
bool can_install_cbm_on_bp (const std::vector< bodypart_id > &bps) const
 
resistances mutation_armor (bodypart_id bp) const
 Returns resistances on a body part provided by mutations. More...
 
float mutation_armor (bodypart_id bp, damage_type dt) const
 
float mutation_armor (bodypart_id bp, const damage_unit &du) const
 
bool activate_bionic (bionic &bio, bool eff_only=false)
 Handles bionic activation effects of the entered bionic, returns if anything activated. More...
 
std::vector< bionic_idget_bionics () const
 
bionicget_bionic_state (const bionic_id &id)
 Get state of bionic with given id. More...
 
std::pair< int, int > amount_of_storage_bionics () const
 Returns amount of Storage CBMs in the corpse. More...
 
bool has_bionic (const bionic_id &b) const
 Returns true if the player has the entered bionic id. More...
 
bool has_active_bionic (const bionic_id &b) const
 Returns true if the player has the entered bionic id and it is powered on. More...
 
bool has_any_bionic () const
 Returns true if the player has any bionic. More...
 
bool can_fuel_bionic_with (const item &it) const
 Returns true if the character can fuel a bionic with the item. More...
 
std::vector< bionic_idget_bionic_fueled_with (const item &it) const
 Return bionic_id of bionics able to use it as fuel. More...
 
std::vector< bionic_idget_fueled_bionics () const
 Return bionic_id of fueled bionics. More...
 
bionic_id get_remote_fueled_bionic () const
 Returns bionic_id of first remote fueled bionic found. More...
 
bionic_id get_most_efficient_bionic (const std::vector< bionic_id > &bids) const
 Return bionic_id of bionic of most fuel efficient bionic. More...
 
std::vector< itype_idget_fuel_available (const bionic_id &bio) const
 Return list of available fuel for this bionic. More...
 
int get_fuel_capacity (const itype_id &fuel) const
 Return available space to store specified fuel. More...
 
int get_total_fuel_capacity (const itype_id &fuel) const
 Return total space to store specified fuel. More...
 
void update_fuel_storage (const itype_id &fuel)
 Updates which bionic contain fuel and which is empty. More...
 
int get_mod_stat_from_bionic (const character_stat &Stat) const
 Get stat bonus from bionic. More...
 
void process_bionic (bionic &bio)
 Handles bionic effects over time of the entered bionic. More...
 
bool deactivate_bionic (bionic &bio, bool eff_only=false)
 Handles bionic deactivation effects of the entered bionic, returns if anything deactivated. More...
 
bool has_bionics () const
 Whether character has any bionics installed. More...
 
void clear_bionics ()
 Remove all bionics. More...
 
int get_used_bionics_slots (const bodypart_id &bp) const
 
int get_total_bionics_slots (const bodypart_id &bp) const
 
int get_free_bionics_slots (const bodypart_id &bp) const
 
bool has_enough_anesth (const itype *cbm, player &patient)
 Has enough anesthetic for surgery. More...
 
void introduce_into_anesthesia (const time_duration &duration, player &installer, bool needs_anesthesia)
 Handles process of introducing patient into anesthesia during Autodoc operations. More...
 
void remove_bionic (const bionic_id &b)
 Removes a bionic from my_bionics[]. More...
 
void add_bionic (const bionic_id &b)
 Adds a bionic to my_bionics[]. More...
 
float env_surgery_bonus (int radius)
 Calculate skill bonus from tiles in radius. More...
 
float bionics_adjusted_skill (const skill_id &most_important_skill, const skill_id &important_skill, const skill_id &least_important_skill, int skill_level=-1)
 Calculate skill for (un)installing bionics. More...
 
int bionics_pl_skill (const skill_id &most_important_skill, const skill_id &important_skill, const skill_id &least_important_skill, int skill_level=-1)
 Calculate non adjusted skill for (un)installing bionics. More...
 
bool can_install_bionics (const itype &type, player &installer, bool autodoc=false, int skill_level=-1)
 Is the installation possible. More...
 
std::map< bodypart_id, int > bionic_installation_issues (const bionic_id &bioid) const
 
bool install_bionics (const itype &type, player &installer, bool autodoc=false, int skill_level=-1)
 Initialize all the values needed to start the operation player_activity. More...
 
void perform_install (bionic_id bid, bionic_id upbid, int difficulty, int success, int pl_skill, const std::string &installer_name, const std::vector< trait_id > &trait_to_rem)
 Success or failure of installation happens here. More...
 
void do_damage_for_bionic_failure (int min_damage, int max_damage)
 
void bionics_install_failure (const std::string &installer, int difficulty, int success, float adjusted_skill)
 
bool can_uninstall_bionic (const bionic_id &b_id, player &installer, bool autodoc=false, int skill_level=-1)
 Is The uninstallation possible. More...
 
bool uninstall_bionic (const bionic_id &b_id, player &installer, bool autodoc=false, int skill_level=-1)
 Initialize all the values needed to start the operation player_activity. More...
 
void perform_uninstall (bionic_id bid, int difficulty, int success, const units::energy &power_lvl, int pl_skill)
 Succes or failure of removal happens here. More...
 
void bionics_uninstall_failure (int difficulty, int success, float adjusted_skill)
 When a player fails the surgery. More...
 
bool uninstall_bionic (const bionic &target_cbm, monster &installer, player &patient, float adjusted_skill)
 Used by monster to perform surgery. More...
 
void bionics_uninstall_failure (monster &installer, player &patient, int difficulty, int success, float adjusted_skill)
 When a monster fails the surgery. More...
 
bool burn_fuel (bionic &bio, bool start=false)
 Convert fuel to bionic power. More...
 
void passive_power_gen (bionic &bio)
 Passively produce power from PERPETUAL fuel. More...
 
itype_id find_remote_fuel (bool look_only=false)
 Find fuel used by remote powered bionic. More...
 
int consume_remote_fuel (int amount)
 Consume fuel used by remote powered bionic, return amount of request unfulfilled (0 if totally successful). More...
 
void reset_remote_fuel ()
 
void heat_emission (bionic &bio, int fuel_energy)
 Handle heat from exothermic power generation. More...
 
float get_effective_efficiency (bionic &bio, float fuel_efficiency)
 Applies modifier to fuel_efficiency and returns the resulting efficiency. More...
 
units::energy get_power_level () const
 
units::energy get_max_power_level () const
 
void mod_power_level (const units::energy &npower)
 
void mod_max_power_level (const units::energy &npower_max)
 
void set_power_level (const units::energy &npower)
 
void set_max_power_level (const units::energy &npower_max)
 
bool is_max_power () const
 
bool has_power () const
 
bool has_max_power () const
 
bool enough_power_for (const bionic_id &bid) const
 
void conduct_blood_analysis () const
 
bool is_worn (const item &thing) const
 
virtual bool invoke_item (item *, const tripoint &pt)
 Asks how to use the item (if it has more than one use_method) and uses it. More...
 
virtual bool invoke_item (item *, const std::string &, const tripoint &pt)
 As above, but with a pre-selected method. More...
 
virtual bool invoke_item (item *)
 As above two, but with position equal to current position. More...
 
virtual bool invoke_item (item *, const std::string &)
 
virtual bool dispose_item (item_location &&obj, const std::string &prompt=std::string())
 Drop, wear, stash or otherwise try to dispose of an item consuming appropriate moves. More...
 
bool has_enough_charges (const item &it, bool show_msg) const
 Has the item enough charges to invoke its use function? Also checks if UPS from this player is used instead of item charges. More...
 
bool consume_charges (item &used, int qty)
 Consume charges of a tool or comestible item, potentially destroying it in the process. More...
 
int item_handling_cost (const item &it, bool penalties=true, int base_cost=INVENTORY_HANDLING_PENALTY) const
 Calculate (but do not deduct) the number of moves required when handling (e.g. More...
 
int item_store_cost (const item &it, const item &container, bool penalties=true, int base_cost=INVENTORY_HANDLING_PENALTY) const
 Calculate (but do not deduct) the number of moves required when storing an item in a container. More...
 
int item_wear_cost (const item &it) const
 Calculate (but do not deduct) the number of moves required to wear an item. More...
 
int amount_worn (const itype_id &id) const
 Returns the amount of item ‘type’ that is currently worn. More...
 
std::vector< item_locationnearby (const std::function< bool(const item *, const item *)> &func, int radius=1) const
 Returns nearby items which match the provided predicate. More...
 
std::list< itemremove_worn_items_with (std::function< bool(item &)> filter)
 Similar to remove_items_with, but considers only worn items and not their content (item::contents is not checked). More...
 
iteminvlet_to_item (int invlet)
 Return the item pointer of the item with given invlet, return nullptr if the player does not have such an item with that invlet. More...
 
itemi_at (int position)
 
const itemi_at (int position) const
 
int get_item_position (const item *it) const
 Returns the item position (suitable for i_at or similar) of a specific item. More...
 
const itemused_weapon () const
 Returns a reference to the item which will be used to make attacks. More...
 
itemused_weapon ()
 
int i_add_to_container (const item &it, bool unloading)
 Try to find a container/s on character containing ammo of type it.typeId() and add charges until the container is full. More...
 
itemi_add (item it, bool should_stack=true)
 
item i_rem (int pos)
 Remove a specific item from player possession. More...
 
item i_rem (const item *it)
 Remove a specific item from player possession. More...
 
void i_rem_keep_contents (int idx)
 
bool i_add_or_drop (item &it, int qty=1)
 Sets invlet and adds to inventory if possible, drops otherwise, returns true if either succeeded. More...
 
std::bitset< std::numeric_limits< char >::max()> allocated_invlets () const
 Only use for UI things. More...
 
bool has_active_item (const itype_id &id) const
 Whether the player carries an active item of the given item type. More...
 
item remove_weapon ()
 
bool has_mission_item (int mission_id) const
 
void remove_mission_items (int mission_id)
 
int throw_range (const item &) const
 Maximum thrown range with a given item, taking all active effects into account. More...
 
bool unarmed_attack () const
 True if unarmed or wielding a weapon with the UNARMED_WEAPON flag. More...
 
int best_nearby_lifting_assist () const
 Checks for items, tools, and vehicles with the Lifting quality near the character returning the highest quality in range. More...
 
int best_nearby_lifting_assist (const tripoint &world_pos) const
 Alternate version if you need to specify a different orign point for nearby vehicle sources of lifting used for operations on distant objects (e.g. More...
 
std::vector< item * > inv_dump ()
 
units::mass weight_carried () const
 
units::volume volume_carried () const
 
units::mass weight_carried_reduced_by (const excluded_stacks &without) const
 
units::volume volume_carried_reduced_by (const excluded_stacks &without) const
 
units::mass weight_capacity () const override
 
units::volume volume_capacity () const
 
units::volume volume_capacity_reduced_by (const units::volume &mod, const excluded_stacks &without={}) const
 
bool can_pick_volume (const item &it) const
 
bool can_pick_volume (units::volume volume) const
 
bool can_pick_weight (const item &it, bool safe=true) const
 
bool can_pick_weight (units::mass weight, bool safe=true) const
 
bool can_use (const item &it, const item &context=item()) const
 Checks if character stats and skills meet minimum requirements for the item. More...
 
ret_val< bool > can_wear (const item &it, bool with_equip_change=false) const
 Check character capable of wearing an item. More...
 
cata::optional< std::list< item >::iterator > wear_possessed (item &to_wear, bool interactive=true)
 Wear specified item. More...
 
cata::optional< std::list< item >::iterator > wear_item (const item &to_wear, bool interactive=true)
 Wear a copy of specified item. More...
 
ret_val< bool > can_takeoff (const item &it, const std::list< item > *res=nullptr) const
 Check if character is capable of taking off given item. More...
 
bool takeoff (item &it, std::list< item > *res=nullptr)
 Take off an item. More...
 
bool is_armed () const
 Returns true if the character is wielding something. More...
 
ret_val< bool > can_wield (const item &it) const
 Check whether character is capable of wielding given item. More...
 
virtual bool wield (item &target)=0
 Removes currently wielded item (if any) and replaces it with the target item. More...
 
ret_val< bool > can_unwield (const item &it) const
 Check whether character is capable of unwielding given item. More...
 
bool unwield ()
 Removes currently wielded item (if any) More...
 
ret_val< bool > can_swap (const item &it) const
 Check player capable of swapping the side of a worn item. More...
 
void drop_invalid_inventory ()
 
std::list< item * > get_dependent_worn_items (const item &it) const
 Returns all items that must be taken off before taking off this item. More...
 
void drop (item_location loc, const tripoint &where)
 Drops an item to the specified location. More...
 
virtual void drop (const drop_locations &what, const tripoint &target, bool stash=false)
 
virtual bool has_artifact_with (art_effect_passive effect) const
 
bool is_wielding (const item &target) const
 
bool covered_with_flag (const std::string &flag, const body_part_set &parts) const
 
bool is_waterproof (const body_part_set &parts) const
 
int leak_level (const std::string &flag) const
 
bool can_reload (const item &it, const itype_id &ammo=itype_id()) const
 Whether a tool or gun is potentially reloadable (optionally considering a specific ammo) More...
 
int item_reload_cost (const item &it, const item &ammo, int qty) const
 Calculate (but do not deduct) the number of moves required to reload an item with specified quantity of ammo. More...
 
bool is_wearing (const item &itm) const
 Returns true if the player is wearing the item. More...
 
bool is_wearing (const itype_id &it) const
 Returns true if the player is wearing an item of this type. More...
 
bool is_wearing_on_bp (const itype_id &it, const bodypart_id &bp) const
 Returns true if the player is wearing the item on the given body part. More...
 
bool worn_with_flag (const std::string &flag, const bodypart_id &bp=bodypart_str_id::NULL_ID()) const
 Returns true if the player is wearing an item with the given flag. More...
 
const itemitem_worn_with_flag (const std::string &flag, const bodypart_id &bp=bodypart_str_id::NULL_ID()) const
 Returns the first worn item with a given flag. More...
 
std::vector< std::string > get_overlay_ids () const
 Returns a list of the IDs of overlays on this character, sorted from "lowest" to "highest". More...
 
int get_skill_level (const skill_id &ident) const
 
int get_skill_level (const skill_id &ident, const item &context) const
 
const SkillLevelMapget_all_skills () const
 
SkillLevelget_skill_level_object (const skill_id &ident)
 
const SkillLevelget_skill_level_object (const skill_id &ident) const
 
void set_skill_level (const skill_id &ident, int level)
 
void mod_skill_level (const skill_id &ident, int delta)
 
bool meets_skill_requirements (const std::map< skill_id, int > &req, const item &context=item()) const
 Checks whether the character's skills meet the required. More...
 
bool meets_skill_requirements (const construction &con) const
 Checks whether the character's skills meet the required. More...
 
bool meets_stat_requirements (const item &it) const
 Checks whether the character's stats meets the stats required by the item. More...
 
bool meets_requirements (const item &it, const item &context=item()) const
 Checks whether the character meets overall requirements to be able to use the item. More...
 
std::string enumerate_unmet_requirements (const item &it, const item &context=item()) const
 Returns a string of missed requirements (both stats and skills) More...
 
int rust_rate () const
 Returns the player's skill rust rate. More...
 
void practice (const skill_id &id, int amount, int cap=99, bool suppress_warning=false)
 This handles giving xp for a skill. More...
 
int read_speed (bool return_stat_effect=true) const
 Returns the player's reading speed. More...
 
time_point get_time_died () const
 return the calendar::turn the character expired More...
 
void set_time_died (const time_point &time)
 set the turn the turn the character died if not already done More...
 
void die (Creature *nkiller) override
 Empty function. More...
 
std::string get_name () const override
 
std::vector< std::string > get_grammatical_genders () const override
 
template<typename ... Args>
bool query_yn (const char *const msg, Args &&... args) const
 It is supposed to hide the query_yn to simplify player vs. More...
 
virtual bool query_yn (const std::string &msg) const =0
 
bool is_immune_field (const field_type_id &fid) const override
 Returns true if we are immune to the field type with the given fid. More...
 
bool is_elec_immune () const override
 Returns true is the player is protected from electric shocks. More...
 
bool is_immune_effect (const efftype_id &) const override
 Returns true if the player is immune to this kind of effect. More...
 
bool is_immune_damage (damage_type) const override
 Returns true if the player is immune to this kind of damage. More...
 
bool is_rad_immune () const
 Returns true if the player is protected from radiation. More...
 
bool is_throw_immune () const
 Returns true if the player is immune to throws. More...
 
bool has_nv ()
 Returns true if the player has some form of night vision. More...
 
float rest_quality () const
 Returns >0 if character is sitting/lying and relatively inactive. More...
 
float healing_rate (float at_rest_quality) const
 Average hit points healed per turn. More...
 
float healing_rate_medicine (float at_rest_quality, const bodypart_id &bp) const
 Average hit points healed per turn from healing effects. More...
 
float mutation_value (const std::string &val) const
 Goes over all mutations, gets min and max of a value with given name. More...
 
social_modifiers get_mutation_social_mods () const
 Goes over all mutations, returning the sum of the social modifiers. More...
 
nc_color basic_symbol_color () const override
 
nc_color symbol_color () const override
 
std::string extended_description () const override
 
void pick_name (bool bUseDefault=false)
 Returns a random name from NAMES_*. More...
 
std::vector< trait_idget_base_traits () const
 Get the idents of all base traits. More...
 
std::vector< trait_idget_mutations (bool include_hidden=true) const
 Get the idents of all traits/mutations. More...
 
const std::bitset< NUM_VISION_MODES > & get_vision_modes () const
 
void clear_skills ()
 Clear the skills map, setting all levels to 0. More...
 
void clear_mutations ()
 Empties the trait and mutations lists. More...
 
bool crossed_threshold () const
 Returns true if the player has crossed a mutation threshold Player can only cross one mutation threshold. More...
 
void add_addiction (add_type type, int strength)
 Adds an addiction to the player. More...
 
void rem_addiction (add_type type)
 Removes an addition from the player. More...
 
bool has_addiction (add_type type) const
 Returns true if the player has an addiction of the specified type. More...
 
int addiction_level (add_type type) const
 Returns the intensity of the specified addiction. More...
 
void start_hauling ()
 
void stop_hauling ()
 
bool is_hauling () const
 
bool has_item_with_flag (const std::string &flag, bool need_charges=false) const
 
std::vector< const item * > all_items_with_flag (const std::string &flag) const
 All items that have the given flag (item::has_flag). More...
 
bool has_charges (const itype_id &it, int quantity, const std::function< bool(const item &)> &filter=return_true< item >) const
 
std::list< itemuse_amount (itype_id it, int quantity, const std::function< bool(const item &)> &filter=return_true< item >)
 
bool use_charges_if_avail (const itype_id &it, int quantity)
 
std::list< itemuse_charges (const itype_id &what, int qty, const std::function< bool(const item &)> &filter=return_true< item >)
 
bool has_fire (int quantity) const
 
void use_fire (int quantity)
 
void assign_stashed_activity ()
 
bool check_outbounds_activity (const player_activity &act, bool check_only=false)
 
void assign_activity (const activity_id &type, int moves=calendar::INDEFINITELY_LONG, int index=-1, int pos=INT_MIN, const std::string &name="")
 Legacy activity assignment, does not work for any activites using the new activity_actor class and may cause issues with resuming. More...
 
void assign_activity (const player_activity &act, bool allow_resume=true)
 Assigns activity to player, possibly resuming old activity if it's similar enough. More...
 
bool has_activity (const activity_id &type) const
 Check if player currently has a given activity. More...
 
bool has_activity (const std::vector< activity_id > &types) const
 Check if player currently has any of the given activities. More...
 
void resume_backlog_activity ()
 
void cancel_activity ()
 
void cancel_stashed_activity ()
 
player_activity get_stashed_activity () const
 
void set_stashed_activity (const player_activity &act, const player_activity &act_back=player_activity())
 
bool has_stashed_activity () const
 
void initialize_stomach_contents ()
 
float metabolic_rate_base () const
 Stable base metabolic rate due to traits. More...
 
float metabolic_rate () const
 Current metabolic rate due to traits, hunger, speed, etc. More...
 
std::string get_weight_string () const
 
int get_max_healthy () const
 
float bmi () const
 
int bmr () const
 
void reset_chargen_attributes ()
 
int base_age () const
 
void set_base_age (int age)
 
void mod_base_age (int mod)
 
int age () const
 
std::string age_string () const
 
int base_height () const
 
void set_base_height (int height)
 
void mod_base_height (int mod)
 
std::string height_string () const
 
int height () const
 
units::mass bodyweight () const
 
units::mass bionics_weight () const
 
int get_armor_bash (bodypart_id bp) const override
 Returns overall bashing resistance for the body_part. More...
 
int get_armor_cut (bodypart_id bp) const override
 Returns overall cutting resistance for the body_part. More...
 
int get_armor_bullet (bodypart_id bp) const override
 Returns overall bullet resistance for the body_part. More...
 
int get_armor_bash_base (bodypart_id bp) const override
 Returns bashing resistance from the creature and armor only. More...
 
int get_armor_cut_base (bodypart_id bp) const override
 Returns cutting resistance from the creature and armor only. More...
 
int get_armor_bullet_base (bodypart_id bp) const override
 Returns cutting resistance from the creature and armor only. More...
 
int get_env_resist (bodypart_id bp) const override
 Returns overall env_resist on a body_part. More...
 
int get_armor_acid (bodypart_id bp) const
 Returns overall acid resistance for the body part. More...
 
int get_armor_type (damage_type dt, bodypart_id bp) const override
 Returns overall resistance to given type on the bod part. More...
 
std::map< bodypart_id, int > get_all_armor_type (damage_type dt, const std::map< bodypart_id, std::vector< const item * > > &clothing_map) const
 
int get_stim () const
 
void set_stim (int new_stim)
 
void mod_stim (int mod)
 
int get_rad () const
 
void set_rad (int new_rad)
 
void mod_rad (int mod)
 
int get_stamina () const
 
int get_stamina_max () const
 
void set_stamina (int new_stamina)
 
void mod_stamina (int mod)
 
void burn_move_stamina (int moves)
 
float stamina_move_cost_modifier () const
 
void update_stamina (int turns)
 Regenerates stamina. More...
 
void on_item_wear (const item &it)
 Called when an item is worn. More...
 
void on_item_takeoff (const item &it)
 Called when an item is taken off. More...
 
void on_worn_item_washed (const item &it)
 Called when an item is washed. More...
 
void on_effect_int_change (const efftype_id &effect_type, int intensity, const bodypart_str_id &bp) override
 Called when effect intensity has been changed. More...
 
void on_mutation_gain (const trait_id &mid)
 Called when a mutation is gained. More...
 
void on_mutation_loss (const trait_id &mid)
 Called when a mutation is lost. More...
 
void on_stat_change (const std::string &stat, int value) override
 Called when a stat is changed. More...
 
void on_worn_item_transform (const item &old_it, const item &new_it)
 Called when a worn item is transformed. More...
 
void wake_up ()
 Removes "sleep" and "lying_down". More...
 
int get_shout_volume () const
 
void shout (std::string msg="", bool order=false)
 
void vomit ()
 Handles Character vomiting effects. More...
 
void healed_bp (int bp, int amount)
 
int adjust_for_focus (int amount) const
 
void update_type_of_scent (bool init=false)
 
void update_type_of_scent (const trait_id &mut, bool gain=true)
 
void set_type_of_scent (const scenttype_id &id)
 
scenttype_id get_type_of_scent () const
 
void restore_scent ()
 restore scent after masked_scent effect run out or is removed by water More...
 
void mod_painkiller (int npkill)
 Modifies intensity of painkillers
More...
 
void set_painkiller (int npkill)
 Sets intensity of painkillers
More...
 
int get_painkiller () const
 Returns intensity of painkillers
More...
 
void react_to_felt_pain (int intensity)
 
void mod_pain (int npain) override
 Modifies a pain value by player traits before passing it to Creature::mod_pain() More...
 
void set_pain (int npain) override
 Sets new intensity of pain an reacts to it. More...
 
int get_perceived_pain () const override
 Returns perceived pain (reduced with painkillers) More...
 
void spores ()
 
void blossoms ()
 
void rooted_message () const
 Handles rooting effects. More...
 
void rooted ()
 
void fall_asleep ()
 Adds "sleep" to the player. More...
 
void fall_asleep (const time_duration &duration)
 
std::string is_snuggling () const
 Checks to see if the player is using floor items to keep warm, and return the name of one such item if so. More...
 
float power_rating () const override
 Returns an approximation of the creature's strength. More...
 
float speed_rating () const override
 Returns an approximate number of tiles this creature can travel per turn. More...
 
itemitem_with_best_of_quality (const quality_id &qid)
 Returns the item in the player's inventory with the highest of the specified quality. More...
 
bool sees_with_infrared (const Creature &critter) const
 Check whether the this player can see the other creature with infrared. More...
 
void place_corpse ()
 
void place_corpse (const tripoint_abs_omt &om_target)
 
int run_cost (int base_cost, bool diag=false) const
 Returns the player's modified base movement cost. More...
 
const pathfinding_settingsget_pathfinding_settings () const override
 Returns settings for pathfinding. More...
 
std::set< tripointget_path_avoid () const override
 Returns a set of points we do not want to path through. More...
 
std::vector< Creature * > get_hostile_creatures (int range) const
 Get all hostile creatures currently visible to this player. More...
 
std::vector< Creature * > get_visible_creatures (int range) const
 Returns all creatures that this player can see and that are in the given range. More...
 
std::string visible_mutations (int visibility_cap) const
 Returns an enumeration of visible mutations with colors. More...
 
player_activity get_destination_activity () const
 
void set_destination_activity (const player_activity &new_destination_activity)
 
void clear_destination_activity ()
 
std::map< bodypart_id, int > warmth (const std::map< bodypart_id, std::vector< const item * > > &clothing_map) const
 Returns warmth provided by armor, etc. More...
 
bool can_use_floor_warmth () const
 Can the player lie down and cover self with blankets etc. More...
 
int floor_warmth (const tripoint &pos) const
 Final warmth from the floor. More...
 
int bodytemp_modifier_traits (bool overheated) const
 Correction factor of the body temperature due to traits and mutations. More...
 
int bodytemp_modifier_traits_floor () const
 Correction factor of the body temperature due to traits and mutations for player lying on the floor. More...
 
int temp_corrected_by_climate_control (int temperature) const
 Value of the body temperature corrected by climate control. More...
 
bool in_sleep_state () const override
 
void update_vitamins (const vitamin_id &vit)
 Set vitamin deficiency/excess disease states dependent upon current vitamin levels. More...
 
int vitamin_get (const vitamin_id &vit) const
 Check current level of a vitamin. More...
 
bool vitamin_set (const vitamin_id &vit, int qty)
 Sets level of a vitamin or returns false if id given in vit does not exist. More...
 
int vitamin_mod (const vitamin_id &vit, int qty, bool capped=true)
 Add or subtract vitamins from character storage pools. More...
 
void vitamins_mod (const std::map< vitamin_id, int > &, bool capped=true)
 
time_duration vitamin_rate (const vitamin_id &vit) const
 Get vitamin usage rate (minutes per unit) accounting for bionics, mutations and effects. More...
 
int nutrition_for (const item &comest) const
 Handles the nutrition value for a comestible. More...
 
ret_val< edible_ratingcan_eat (const item &food) const
 Can the food be [theoretically] eaten no matter the consequen ces? More...
 
ret_val< edible_ratingwill_eat (const item &food, bool interactive=false) const
 Same as can_eat, but takes consequences into account. More...
 
bool can_feed_reactor_with (const item &it) const
 Determine character's capability of recharging their CBMs. More...
 
bool can_feed_furnace_with (const item &it) const
 
rechargeable_cbm get_cbm_rechargeable_with (const item &it) const
 
int get_acquirable_energy (const item &it, rechargeable_cbm cbm) const
 
int get_acquirable_energy (const item &it) const
 
bool feed_reactor_with (item &it)
 Recharge CBMs whenever possible. More...
 
bool feed_furnace_with (item &it)
 
bool fuel_bionic_with (item &it)
 
void modify_stimulation (const islot_comestible &comest)
 Used to apply stimulation modifications from food and medication. More...
 
void modify_fatigue (const islot_comestible &comest)
 Used to apply fatigue modifications from food and medication. More...
 
void modify_radiation (const islot_comestible &comest)
 Used to apply radiation from food and medication. More...
 
void modify_addiction (const islot_comestible &comest)
 Used to apply addiction modifications from food and medication. More...
 
void modify_health (const islot_comestible &comest)
 Used to apply health modifications from food and medication. More...
 
bool consume_effects (item &food)
 Handles the effects of consuming an item. More...
 
bool can_consume (const item &it) const
 Check character's capability of consumption overall. More...
 
bool can_estimate_rot () const
 True if the character has enough skill (in cooking or survival) to estimate time to rot. More...
 
bool can_consume_as_is (const item &it) const
 Check whether character can consume this very item. More...
 
bool can_consume_for_bionic (const item &it) const
 
itemget_consumable_from (item &it) const
 Returns a reference to the item itself (if it's consumable), the first of its contents (if it's consumable) or null item otherwise. More...
 
void consume (item_location loc)
 Consume item (food, fuel, medicine, ...) at given location loc . More...
 
bool consume_item (item &target)
 Consume given item (food, fuel, medicine, ...). More...
 
bool consume_med (item &target)
 Consume an item as medication. More...
 
bool eat (item &food, bool force=false)
 Used for eating entered comestible, returns true if comestible is successfully eaten. More...
 
std::pair< nutrients, nutrientscompute_nutrient_range (const item &, const recipe_id &, const cata::flat_set< std::string > &extra_flags={}) const
 Get calorie & vitamin contents for a comestible, taking into account character traits. More...
 
std::pair< nutrients, nutrientscompute_nutrient_range (const itype_id &, const cata::flat_set< std::string > &extra_flags={}) const
 Same, but across arbitrary recipes. More...
 
morale_type allergy_type (const item &food) const
 Returns allergy type or MORALE_NULL if not allergic for this character. More...
 
nutrients compute_effective_nutrients (const item &) const
 
bool wearing_something_on (const bodypart_id &bp) const
 Returns true if the character is wearing something on the entered body part. More...
 
bool is_wearing_helmet () const
 Returns true if the character is wearing something occupying the helmet slot. More...
 
int head_cloth_encumbrance () const
 Returns the total encumbrance of all SKINTIGHT and HELMET_COMPAT items coveringi the head. More...
 
double armwear_factor () const
 Same as footwear factor, but for arms. More...
 
int shoe_type_count (const itype_id &it) const
 Returns 1 if the player is wearing an item of that count on one foot, 2 if on both, and zero if on neither. More...
 
double footwear_factor () const
 Returns 1 if the player is wearing something on both feet, .5 if on one, and 0 if on neither. More...
 
bool is_wearing_shoes (const side &which_side=side::BOTH) const
 Returns true if the player is wearing something on their feet that is not SKINTIGHT. More...
 
bool change_side (item &it, bool interactive=true)
 Swap side on which item is worn; returns false on fail. More...
 
bool change_side (item_location &loc, bool interactive=true)
 
bool get_check_encumbrance ()
 
void set_check_encumbrance (bool new_check)
 
void update_morale ()
 Ticks down morale counters and removes them. More...
 
void apply_persistent_morale ()
 Ensures persistent morale effects are up-to-date. More...
 
void modify_morale (item &food, int nutr=0)
 Used to apply morale modifications from food and medication. More...
 
int get_morale_level () const
 
void add_morale (const morale_type &type, int bonus, int max_bonus=0, const time_duration &duration=1_hours, const time_duration &decay_start=30_minutes, bool capped=false, const itype *item_type=nullptr)
 
bool has_morale (const morale_type &type) const
 
int get_morale (const morale_type &type) const
 
void rem_morale (const morale_type &type)
 
void clear_morale ()
 
bool has_morale_to_read () const
 
bool has_morale_to_craft () const
 
const inventorycrafting_inventory (bool clear_path)
 
const inventorycrafting_inventory (const tripoint &src_pos=tripoint_zero, int radius=PICKUP_RANGE, bool clear_path=true)
 
void invalidate_crafting_inventory ()
 
const recipe_subsetget_learned_recipes () const
 Returns all known recipes. More...
 
bool knows_recipe (const recipe *rec) const
 
void learn_recipe (const recipe *rec)
 
bool can_learn_by_disassembly (const recipe &rec) const
 
bool check_and_recover_morale ()
 Checks permanent morale for consistency and recovers it when an inconsistency is found. More...
 
std::pair< int, int > fun_for (const item &comest) const
 Handles the enjoyability value for a comestible. More...
 
void suffer ()
 Handles a large number of timers decrementing and other randomized effects. More...
 
bool irradiate (float rads, bool bypass=false)
 Handles mitigation and application of radiation. More...
 
void mend (int rate_multiplier)
 Handles the chance for broken limbs to spontaneously heal to 1 HP. More...
 
void sound_hallu ()
 Creates an auditory hallucination. More...
 
void drench (int saturation, const body_part_set &flags, bool ignore_waterproof)
 Drenches the player with water, saturation is the percent gotten wet. More...
 
void apply_wetness_morale (int temperature)
 Recalculates morale penalty/bonus from wetness based on mutations, equipment and temperature. More...
 
std::vector< std::string > short_description_parts () const
 
std::string short_description () const
 
int print_info (const catacurses::window &w, int vStart, int vLines, int column) const override
 Write information about this creature. More...
 
bool can_hear (const tripoint &source, int volume) const
 
float hearing_ability () const
 
bool knows_trap (const tripoint &pos) const
 
void add_known_trap (const tripoint &pos, const trap &t)
 
bool avoid_trap (const tripoint &pos, const trap &tr) const override
 Called when character triggers a trap, returns true if they don't set it off. More...
 
nc_color bodytemp_color (int bp) const
 Define color for displaying the body temperature. More...
 
bool sees (const tripoint &t, bool is_player=false, int range_mod=0) const override
 
bool sees (const Creature &critter) const override
 The functions check whether this creature can see the target. More...
 
Attitude attitude_to (const Creature &other) const override
 Attitude (of this creature) towards another creature. More...
 
int get_lowest_hp () const
 
bool has_weapon () const override
 
void shift_destination (const point &shift)
 
void set_destination (const std::vector< tripoint > &route, const player_activity &new_destination_activity=player_activity())
 
void clear_destination ()
 
bool has_distant_destination () const
 
bool is_auto_moving () const
 
bool has_destination () const
 
bool has_destination_activity () const
 
void start_destination_activity ()
 
std::vector< tripoint > & get_auto_move_route ()
 
action_id get_next_auto_move_direction ()
 
bool defer_move (const tripoint &next)
 
std::map< bodypart_id, float > bodypart_exposure ()
 Map body parts to their total exposure, from 0.0 (fully covered) to 1.0 (buck naked). More...
 
void set_underwater (bool x) override
 
void clear_npc_ai_info_cache (const std::string &key) const
 
void set_npc_ai_info_cache (const std::string &key, double val) const
 
cata::optional< double > get_npc_ai_info_cache (const std::string &key) const
 
safe_reference< Characterget_safe_reference ()
 
bool pour_into (item &container, item &liquid)
 Try to pour the given liquid into the given container/vehicle. More...
 
bool pour_into (vehicle &veh, item &liquid)
 
- Public Member Functions inherited from Creature
virtual ~Creature ()
 
virtual bool is_player () const
 
virtual bool is_avatar () const
 
virtual bool is_npc () const
 
virtual bool is_monster () const
 
virtual monsteras_monster ()
 
virtual const monsteras_monster () const
 
virtual npcas_npc ()
 
virtual const npcas_npc () const
 
virtual playeras_player ()
 
virtual const playeras_player () const
 
virtual avataras_avatar ()
 
virtual const avataras_avatar () const
 
virtual bool is_fake () const
 Returns true for non-real Creatures used temporarily; i.e. More...
 
virtual void set_fake (bool fake_value)
 Sets a Creature's fake boolean. More...
 
virtual void bleed () const
 Adds an appropriate blood splatter. More...
 
Creatureauto_find_hostile_target (int range, int &boo_hoo, int area=0)
 For fake-players (turrets, mounted turrets) this functions chooses a target. More...
 
double ranged_target_size () const
 Size of the target this creature presents to ranged weapons. More...
 
void knock_back_from (const tripoint &p)
 
int size_melee_penalty () const
 
virtual int deal_melee_attack (Creature *source, int hitroll)
 
virtual void deal_melee_hit (Creature *source, int hit_spread, bool critical_hit, const damage_instance &dam, dealt_damage_instance &dealt_dam)
 
virtual void deal_projectile_attack (Creature *source, dealt_projectile_attack &attack)
 Attempts to harm a creature with a projectile. More...
 
virtual void deal_damage_handle_type (const damage_unit &du, bodypart_id bp, int &damage, int &pain)
 
virtual bool digging () const
 
virtual bool is_underwater () const
 
virtual bool is_hallucination () const =0
 
bool is_dangerous_fields (const field &fld) const
 Returns true if there is a field in the field set that is dangerous to us. More...
 
bool is_dangerous_field (const field_entry &entry) const
 Returns true if the given field entry is dangerous to us. More...
 
void check_dead_state ()
 This function checks the creatures is_dead_state and (if true) calls die. More...
 
void add_effect (const effect &eff, bool force=false, bool deferred=false)
 
virtual void add_effect (const efftype_id &eff_id, const time_duration &dur, const bodypart_str_id &bp, int intensity=0, bool force=false, bool deferred=false)
 Adds or modifies an effect. More...
 
void add_effect (const efftype_id &eff_id, const time_duration &dur, body_part bp=num_bp, int intensity=0, bool force=false, bool deferred=false)
 
bool add_env_effect (const efftype_id &eff_id, body_part vector, int strength, const time_duration &dur, body_part bp=num_bp, int intensity=1, bool force=false)
 Gives chance to save via environmental resist, returns false if resistance was successful. More...
 
bool add_env_effect (const efftype_id &eff_id, body_part vector, int strength, const time_duration &dur, body_part bp, bool REMOVED, int intensity=1, bool force=false)=delete
 
bool remove_effect (const efftype_id &eff_id, body_part bp=num_bp)
 Removes a listed effect. More...
 
virtual bool remove_effect (const efftype_id &eff_id, const bodypart_str_id &bp)
 
void clear_effects ()
 Remove all effects. More...
 
bool has_effect (const efftype_id &eff_id, body_part bp=num_bp) const
 Check if creature has the matching effect. More...
 
bool has_effect (const efftype_id &eff_id, const bodypart_str_id &bp) const
 
bool has_effect_with_flag (const std::string &flag, body_part bp=num_bp) const
 Check if creature has any effect with the given flag. More...
 
const effectget_effect (const efftype_id &eff_id, body_part bp=num_bp) const
 Return the effect that matches the given arguments exactly. More...
 
effectget_effect (const efftype_id &eff_id, body_part bp=num_bp)
 
std::vector< const effect * > get_all_effects_of_type (const efftype_id &eff_id) const
 Returns pointers to all effects matching given type. More...
 
time_duration get_effect_dur (const efftype_id &eff_id, body_part bp=num_bp) const
 Returns the duration of the matching effect. More...
 
int get_effect_int (const efftype_id &eff_id, body_part bp=num_bp) const
 Returns the intensity of the matching effect. More...
 
bool resists_effect (const effect &e) const
 Returns true if the creature resists an effect. More...
 
void set_value (const std::string &key, const std::string &value)
 
void remove_value (const std::string &key)
 
std::string get_value (const std::string &key) const
 
void process_effects ()
 Processes through all the effects on the Creature. More...
 
virtual void mod_pain_noresist (int npain)
 
virtual int get_pain () const
 
int get_moves () const
 
void mod_moves (int nmoves)
 
void set_moves (int nmoves)
 
virtual Creatureget_killer () const
 
virtual int get_num_blocks () const
 
virtual int get_num_dodges () const
 
virtual int get_num_blocks_bonus () const
 
virtual int get_num_dodges_bonus () const
 
virtual int get_num_dodges_base () const
 
virtual int get_armor_bash_bonus () const
 
virtual int get_armor_cut_bonus () const
 
virtual int get_armor_bullet_bonus () const
 
virtual float get_hit () const
 
virtual int get_hp (const bodypart_id &bp) const
 
virtual int get_hp () const
 
virtual int get_hp_max (const bodypart_id &bp) const
 
virtual int get_hp_max () const
 
virtual bool has_flag (const m_flag) const
 
anatomy_id get_anatomy () const
 
void set_anatomy (anatomy_id anat)
 
bodypart_id get_random_body_part (bool main=false) const
 
std::vector< bodypart_idget_all_body_parts (bool only_main=false) const
 Returns body parts this creature have. More...
 
const std::map< bodypart_str_id, bodypart > & get_body () const
 
void set_body ()
 
bodypartget_part (const bodypart_id &id)
 
bodypart get_part (const bodypart_id &id) const
 
int get_part_hp_cur (const bodypart_id &id) const
 
int get_part_hp_max (const bodypart_id &id) const
 
int get_part_healed_total (const bodypart_id &id) const
 
void set_part_hp_cur (const bodypart_id &id, int set)
 
void set_part_hp_max (const bodypart_id &id, int set)
 
void set_part_healed_total (const bodypart_id &id, int set)
 
void mod_part_hp_cur (const bodypart_id &id, int mod)
 
void mod_part_hp_max (const bodypart_id &id, int mod)
 
void mod_part_healed_total (const bodypart_id &id, int mod)
 
void set_all_parts_hp_cur (int set)
 
void set_all_parts_hp_to_max ()
 
virtual int get_speed_base () const
 
virtual int get_speed_bonus () const
 
virtual int get_block_bonus () const
 
virtual float get_dodge_bonus () const
 
virtual float get_hit_bonus () const
 
virtual void set_num_blocks_bonus (int nblocks)
 
virtual void mod_num_dodges_bonus (int ndodges)
 
virtual void set_armor_bash_bonus (int nbasharm)
 
virtual void set_armor_cut_bonus (int ncutarm)
 
virtual void set_armor_bullet_bonus (int nbulletarm)
 
virtual void set_speed_base (int nspeed)
 
virtual void set_speed_bonus (int nspeed)
 
virtual void set_block_bonus (int nblock)
 
virtual void mod_speed_bonus (int nspeed)
 
virtual void mod_block_bonus (int nblock)
 
virtual void set_dodge_bonus (float ndodge)
 
virtual void set_hit_bonus (float nhit)
 
virtual void mod_dodge_bonus (float ndodge)
 
virtual void mod_hit_bonus (float nhit)
 
void draw (const catacurses::window &w, const point &origin, bool inverted) const
 
void draw (const catacurses::window &w, const tripoint &origin, bool inverted) const
 
void describe_infrared (std::vector< std::string > &buf) const
 Describe this creature as seen by the avatar via infrared vision. More...
 
void describe_specials (std::vector< std::string > &buf) const
 Describe this creature as detected by the avatar's special senses. More...
 
virtual void add_msg_if_player (const std::string &) const
 
virtual void add_msg_if_player (const game_message_params &, const std::string &) const
 
void add_msg_if_player (const translation &) const
 
void add_msg_if_player (const game_message_params &, const translation &) const
 
template<typename ... Args>
void add_msg_if_player (const char *const msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_player (const std::string &msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_player (const translation &msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_player (const game_message_params &params, const char *const msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_player (const game_message_params &params, const std::string &msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_player (const game_message_params &params, const translation &msg, Args &&... args) const
 
virtual void add_msg_if_npc (const std::string &) const
 
virtual void add_msg_if_npc (const game_message_params &, const std::string &) const
 
void add_msg_if_npc (const translation &) const
 
void add_msg_if_npc (const game_message_params &, const translation &) const
 
template<typename ... Args>
void add_msg_if_npc (const char *const msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_npc (const std::string &msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_npc (const translation &msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_npc (const game_message_params &params, const char *const msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_npc (const game_message_params &params, const std::string &msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_npc (const game_message_params &params, const translation &msg, Args &&... args) const
 
virtual void add_msg_player_or_npc (const std::string &, const std::string &) const
 
virtual void add_msg_player_or_npc (const game_message_params &, const std::string &, const std::string &) const
 
void add_msg_player_or_npc (const translation &, const translation &) const
 
void add_msg_player_or_npc (const game_message_params &, const translation &, const translation &) const
 
template<typename ... Args>
void add_msg_player_or_npc (const char *const player_msg, const char *const npc_msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_npc (const std::string &player_msg, const std::string &npc_msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_npc (const translation &player_msg, const translation &npc_msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_npc (const game_message_params &params, const char *const player_msg, const char *const npc_msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_npc (const game_message_params &params, const std::string &player_msg, const std::string &npc_msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_npc (const game_message_params &params, const translation &player_msg, const translation &npc_msg, Args &&... args) const
 
virtual void add_msg_player_or_say (const std::string &, const std::string &) const
 
virtual void add_msg_player_or_say (const game_message_params &, const std::string &, const std::string &) const
 
void add_msg_player_or_say (const translation &, const translation &) const
 
void add_msg_player_or_say (const game_message_params &, const translation &, const translation &) const
 
template<typename ... Args>
void add_msg_player_or_say (const char *const player_msg, const char *const npc_speech, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_say (const std::string &player_msg, const std::string &npc_speech, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_say (const translation &player_msg, const translation &npc_speech, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_say (const game_message_params &params, const char *const player_msg, const char *const npc_speech, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_say (const game_message_params &params, const std::string &player_msg, const std::string &npc_speech, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_say (const game_message_params &params, const translation &player_msg, const translation &npc_speech, Args &&... args) const
 
virtual bool is_symbol_highlighted () const
 
effects_map get_all_effects () const
 
body_part select_body_part (Creature *source, int hit_roll) const
 
std::string replace_with_npc_name (std::string input) const
 This function replaces the "<npcname>" substring with the disp_name of this creature. More...
 
- Public Member Functions inherited from visitable< Character >
VisitResponse visit_items (const std::function< VisitResponse(item *, item *)> &func)
 Traverses this object and any child items contained using a visitor pattern. More...
 
VisitResponse visit_items (const std::function< VisitResponse(const item *, const item *)> &func) const
 
VisitResponse visit_items (const std::function< VisitResponse(item *)> &func)
 Lightweight version which provides only the current node. More...
 
VisitResponse visit_items (const std::function< VisitResponse(const item *)> &func) const
 
itemfind_parent (const item &it)
 Determine the immediate parent container (if any) for an item. More...
 
const itemfind_parent (const item &it) const
 
std::vector< item * > parents (const item &it)
 Returns vector of parent containers (if any) starting with the innermost. More...
 
std::vector< const item * > parents (const item &it) const
 
bool has_item (const item &it) const
 Returns true if this visitable instance contains the item. More...
 
bool has_item_with (const std::function< bool(const item &)> &filter) const
 Returns true if any item (including those within a container) matches the filter. More...
 
bool has_quality (const quality_id &qual, int level=1, int qty=1) const
 Returns true if instance has amount (or more) items of at least quality level. More...
 
int max_quality (const quality_id &qual) const
 Return maximum tool quality level provided by instance or INT_MIN if not found. More...
 
int charges_of (const itype_id &what, int limit=INT_MAX, const std::function< bool(const item &)> &filter=return_true< item >, std::function< void(int)> visitor=nullptr) const
 Count maximum available charges from this instance and any contained items. More...
 
int amount_of (const itype_id &what, bool pseudo=true, int limit=INT_MAX, const std::function< bool(const item &)> &filter=return_true< item >) const
 Count items matching id including both this instance and any contained items. More...
 
bool has_amount (const itype_id &what, int qty, bool pseudo=true, const std::function< bool(const item &)> &filter=return_true< item >) const
 Check instance provides at least qty of an item (. More...
 
std::vector< item * > items_with (const std::function< bool(const item &)> &filter)
 Returns all items (including those within a container) matching the filter. More...
 
std::vector< const item * > items_with (const std::function< bool(const item &)> &filter) const
 
std::list< itemremove_items_with (const std::function< bool(const item &)> &filter, int count=INT_MAX)
 Removes items contained by this instance which match the filter. More...
 
item remove_item (item &it)
 Removes and returns the item which must be contained by this instance. More...
 

Static Public Member Functions

static hp_part bp_to_hp (body_part bp)
 Converts a body_part to an hp_part. More...
 
static body_part hp_to_bp (hp_part hpart)
 Converts an hp_part to a body_part. More...
 
static int worn_position_to_index (int position)
 
static int floor_bedding_warmth (const tripoint &pos)
 Warmth from terrain, furniture, vehicle furniture and traps. More...
 
static int floor_item_warmth (const tripoint &pos)
 Warmth from clothing on the floor. More...
 
- Static Public Member Functions inherited from Creature
static std::string attitude_raw_string (Attitude att)
 Simplified attitude string for unlocalized needs. More...
 
static const std::pair< translation, nc_color > & get_attitude_ui_data (Attitude att)
 Creature Attitude as String and color. More...
 
static void load_hit_range (const JsonObject &)
 
static void reset_hit_range ()
 

Public Attributes

bool death_drops = true
 
bool controlling_vehicle = false
 
int str_max = 0
 
int dex_max = 0
 
int int_max = 0
 
int per_max = 0
 
int str_cur = 0
 
int dex_cur = 0
 
int int_cur = 0
 
int per_cur = 0
 
int blocks_left = 0
 
int dodges_left = 0
 
double recoil = MAX_RECOIL
 
profession_id prof
 
std::string custom_profession
 
bool reach_attacking = false
 
pimpl< known_magicmagic
 
std::string name
 
bool male = true
 
std::list< itemworn
 
std::array< int, num_hp_partsdamage_bandaged
 
std::array< int, num_hp_partsdamage_disinfected
 
bool nv_cached = false
 
bool in_vehicle = false
 
bool hauling = false
 
player_activity stashed_outbounds_activity
 
player_activity stashed_outbounds_backlog
 
player_activity activity
 
std::list< player_activitybacklog
 
cata::optional< tripointdestination_point
 
inventory inv
 
itype_id last_item
 
item weapon
 
int scent = 0
 
pimpl< bionic_collectionmy_bionics
 
pimpl< character_martial_artsmartial_arts_data
 
stomach_contents stomach
 
pimpl< consumption_history_tconsumption_history
 
int oxygen = 0
 
int tank_plut = 0
 
int reactor_plut = 0
 
int slow_rad = 0
 
int focus_pool = 0
 
int cash = 0
 
std::set< character_idfollower_ids
 
weak_ptr_fast< Creaturelast_target
 
cata::optional< tripointlast_target_pos
 
item_location ammo_location
 
std::set< tripoint_abs_omtcamps
 
time_point cached_time
 
std::vector< addictionaddictions
 
shared_ptr_fast< monstermounted_creature
 
int mounted_creature_id = 0
 
int activity_vehicle_part_index = -1
 
std::array< int, num_hp_partshealed_total
 
std::map< std::string, int > mutation_category_level
 
std::vector< tripoint_abs_omtomt_path
 Route for overmap scale traveling. More...
 
mutation_collection my_mutations
 Traits / mutations of the character. More...
 
time_point last_sleep_check = calendar::turn_zero
 
bool bio_soporific_powered_at_last_sleep_check = false
 
std::array< int, num_bptemp_cur
 
std::array< int, num_bpfrostbite_timer
 
std::array< int, num_bptemp_conv
 
std::array< int, num_bpbody_wetness
 
std::array< int, num_bpdrench_capacity
 
time_point next_climate_control_check
 
bool last_climate_control_ret = false
 
- Public Attributes inherited from Creature
FacingDirection facing = FD_RIGHT
 return the direction the creature is facing, for sdl horizontal flip More...
 
int moves = 0
 

Static Public Attributes

static const std::vector< material_idfleshy = { material_id( "flesh" ), material_id( "hflesh" ) }
 
- Static Public Attributes inherited from Creature
static const std::map< std::string, m_sizesize_map
 
static const std::set< material_idcmat_flesh
 
static const std::set< material_idcmat_fleshnveg
 
static const std::set< material_idcmat_flammable
 
static const std::set< material_idcmat_flameres
 
static std::vector< int > dispersion_for_even_chance_of_good_hit = default_dispersion_for_ecogh
 

Protected Member Functions

void do_skill_rust ()
 
void apply_mods (const trait_id &mut, bool add_remove)
 Applies stat mods to character. More...
 
char_encumbrance_data calc_encumbrance () const
 Recalculate encumbrance for all body parts. More...
 
char_encumbrance_data calc_encumbrance (const item &new_item) const
 Recalculate encumbrance for all body parts as if new_item was also worn. More...
 
void mut_cbm_encumb (char_encumbrance_data &vals) const
 Applies encumbrance from mutations and bionics only. More...
 
std::list< item >::iterator position_to_wear_new_item (const item &new_item)
 Return the position in the worn list where new_item would be put by default. More...
 
void item_encumb (char_encumbrance_data &vals, const item &new_item) const
 Applies encumbrance from items only If new_item is not null, then calculate under the asumption that it is added to existing work items. More...
 
void on_damage_of_type (int adjusted_damage, damage_type type, const bodypart_id &bp) override
 
 Character ()
 
 Character (Character &&)
 
Characteroperator= (Character &&)
 
void store (JsonOut &json) const
 Load variables from json into object. More...
 
void load (const JsonObject &data)
 Gather variables for saving. More...
 
- Protected Member Functions inherited from Creature
void set_killer (Creature *killer)
 
 Creature ()
 
 Creature (const Creature &)=default
 
 Creature (Creature &&)=default
 
Creatureoperator= (const Creature &)=default
 
Creatureoperator= (Creature &&)=default
 
void store (JsonOut &jsout) const
 These two functions are responsible for storing and loading the members of this class to/from json data. More...
 
void load (const JsonObject &jsin)
 

Protected Attributes

std::array< std::array< int, NUM_WATER_TOLERANCE >, num_bpmut_drench
 
tripoint position
 
int str_bonus = 0
 Bonuses to stats, calculated each turn. More...
 
int dex_bonus = 0
 
int per_bonus = 0
 
int int_bonus = 0
 
int healthy = 0
 How healthy the character is. More...
 
int healthy_mod = 0
 
int init_age = 25
 age in years at character creation More...
 
int init_height = 175
 height at character creation More...
 
m_size size_class = MS_MEDIUM
 Size class of character. More...
 
trap_map known_traps
 
pimpl< char_encumbrance_dataencumbrance_cache
 
std::unordered_set< trait_idmy_traits
 Contains mutation ids of the base traits. More...
 
std::vector< const mutation_branch * > cached_mutations
 Pointers to mutation branches in my_mutations. More...
 
pimpl< SkillLevelMap_skills
 Character skills. More...
 
pimpl< SkillLevelMapautolearn_skills_stamp
 Stamp of character skills. More...
 
pimpl< recipe_subsetlearned_recipes
 Subset of learned recipes. More...
 
std::bitset< NUM_VISION_MODESvision_mode_cache
 
float nv_range = 0
 
int sight_max = 0
 
time_point time_died = calendar::before_time_starts
 
pimpl< pathfinding_settingspath_settings
 Cache for pathfinding settings. More...
 
int faction_api_version = 2
 
faction_id fac_id
 
factionmy_fac = nullptr
 
character_movemode move_mode = CMM_WALK
 
std::map< vitamin_id, int > vitamin_levels
 Current deficiency/excess quantity for each vitamin. More...
 
pimpl< player_moralemorale
 
pimpl< enchantmentenchantment_cache
 
std::unordered_map< point_abs_omt, time_durationovermap_time
 Amount of time the player has spent in each overmap tile. More...
 
- Protected Attributes inherited from Creature
Creaturekiller = nullptr
 
pimpl< effects_mapeffects
 
std::unordered_map< std::string, std::string > values
 
int num_blocks = 0
 
int num_dodges = 0
 
int num_blocks_bonus = 0
 
int num_dodges_bonus = 0
 
int armor_bash_bonus = 0
 
int armor_cut_bonus = 0
 
int armor_bullet_bonus = 0
 
int speed_base = 0
 
int speed_bonus = 0
 
float dodge_bonus = 0.0
 
int block_bonus = 0
 
float hit_bonus = 0.0
 
bool fake = false
 

Private Member Functions

bool valid_aoe_technique (Creature &t, const ma_technique &technique)
 Check if an area-of-effect technique has valid targets. More...
 
bool valid_aoe_technique (Creature &t, const ma_technique &technique, std::vector< Creature * > &targets)
 
int get_mod (const trait_id &mut, const std::string &arg) const
 Retrieves a stat mod of a mutation. More...
 
void apply_skill_boost ()
 Applies skill-based boosts to stats. More...
 
void old_mutate ()
 
void suffer_water_damage (const mutation_branch &mdata)
 suffer() subcalls More...
 
void suffer_mutation_power (const mutation_branch &mdata, char_trait_data &tdata)
 
void suffer_while_underwater ()
 
void suffer_from_addictions ()
 
void suffer_while_awake (int current_stim)
 
void suffer_from_chemimbalance ()
 
void suffer_from_schizophrenia ()
 
void suffer_from_asthma (int current_stim)
 
void suffer_in_sunlight ()
 
void suffer_from_sunburn ()
 
void suffer_from_other_mutations ()
 
void suffer_from_radiation ()
 
void suffer_from_bad_bionics ()
 
void suffer_from_artifacts ()
 
void suffer_from_stimulants (int current_stim)
 
void suffer_without_sleep (int sleep_deprivation)
 
bool is_visible_in_range (const Creature &critter, int range) const
 Check whether the other creature is in range and can be seen by this creature. More...
 

Private Attributes

player_activity destination_activity
 
character_id id
 
units::energy power_level
 
units::energy max_power_level
 
int stored_calories = 0
 Needs (hunger, starvation, thirst, fatigue, etc.) More...
 
int thirst = 0
 
int stamina = 0
 
int fatigue = 0
 
int sleep_deprivation = 0
 
bool check_encumbrance = true
 
int stim = 0
 
int pkill = 0
 
int radiation = 0
 
std::vector< tripointauto_move_route
 
cata::optional< tripointnext_expected_position
 
scenttype_id type_of_scent
 
struct weighted_int_list< std::string > melee_miss_reasons
 
int cached_moves = 0
 
tripoint cached_position
 
inventory cached_crafting_inventory
 
std::map< std::string, double > npc_ai_info_cache
 
safe_reference_anchor anchor
 

Additional Inherited Members

Detailed Description

Definition at line 217 of file character.h.

Member Typedef Documentation

◆ trap_map

using Character::trap_map = std::map<tripoint, std::string>

Definition at line 2050 of file character.h.

Member Enumeration Documentation

◆ water_tolerance

Enumerator
WT_IGNORED 
WT_NEUTRAL 
WT_GOOD 
NUM_WATER_TOLERANCE 

Definition at line 780 of file character.h.

780 {
781 WT_IGNORED = 0,
783 WT_GOOD,
785 };
@ WT_NEUTRAL
Definition: character.h:782
@ WT_IGNORED
Definition: character.h:781
@ NUM_WATER_TOLERANCE
Definition: character.h:784

Constructor & Destructor Documentation

◆ Character() [1/3]

Character::Character ( const Character )
delete

◆ ~Character()

Character::~Character ( )
overridedefault

◆ Character() [2/3]

Character::Character ( )
protected

Definition at line 400 of file character.cpp.

400 :
402 damage_bandaged( {{ 0 }} ),
403 damage_disinfected( {{ 0 }} ),
405 id( -1 ),
408{
409 str_max = 0;
410 dex_max = 0;
411 per_max = 0;
412 int_max = 0;
413 str_cur = 0;
414 dex_cur = 0;
415 per_cur = 0;
416 int_cur = 0;
417 str_bonus = 0;
418 dex_bonus = 0;
419 per_bonus = 0;
420 int_bonus = 0;
421 healthy = 0;
422 healthy_mod = 0;
423 thirst = 0;
424 fatigue = 0;
426 set_rad( 0 );
427 tank_plut = 0;
428 reactor_plut = 0;
429 slow_rad = 0;
430 set_stim( 0 );
431 set_stamina( 10000 ); //Temporary value for stamina. It will be reset later from external json option.
432 set_anatomy( anatomy_id("human_anatomy") );
433 update_type_of_scent( true );
434 pkill = 0;
437 healed_total = { { 0, 0, 0, 0, 0, 0 } };
438
439 name.clear();
440 custom_profession.clear();
442
443 *path_settings = pathfinding_settings{ 0, 1000, 1000, 0, true, true, true, false, true };
444
447 temp_cur.fill( BODYTEMP_NORM );
448 frostbite_timer.fill( 0 );
449 temp_conv.fill( BODYTEMP_NORM );
450
451 body_wetness.fill( 0 );
452
465}
string_id< anatomy > anatomy_id
Definition: anatomy.h:14
@ bp_foot_l
Definition: bodypart.h:50
@ bp_leg_r
Definition: bodypart.h:49
@ bp_eyes
Definition: bodypart.h:42
@ bp_hand_l
Definition: bodypart.h:46
@ bp_arm_l
Definition: bodypart.h:44
@ bp_leg_l
Definition: bodypart.h:48
@ bp_hand_r
Definition: bodypart.h:47
@ bp_head
Definition: bodypart.h:41
@ bp_torso
Definition: bodypart.h:40
@ bp_mouth
Definition: bodypart.h:43
@ bp_foot_r
Definition: bodypart.h:51
@ bp_arm_r
Definition: bodypart.h:45
@ CMM_WALK
Definition: character.h:101
bool last_climate_control_ret
Definition: character.h:2263
character_movemode move_mode
Definition: character.h:2172
int str_max
Definition: character.h:251
std::array< int, num_bp > frostbite_timer
Definition: character.h:2258
void update_type_of_scent(bool init=false)
Definition: character.cpp:8682
int str_cur
Definition: character.h:256
int str_bonus
Bonuses to stats, calculated each turn.
Definition: character.h:2098
profession_id prof
Definition: character.h:565
int dex_cur
Definition: character.h:257
std::array< int, num_bp > temp_conv
Definition: character.h:2258
int max_stored_kcal() const
Definition: character.cpp:4305
int per_max
Definition: character.h:254
void set_stim(int new_stim)
Definition: character.cpp:7020
void set_stamina(int new_stamina)
Definition: character.cpp:7064
std::string name
Definition: character.h:1529
std::array< int, num_bp > body_wetness
Definition: character.h:2259
time_point next_climate_control_check
Definition: character.h:2262
int stored_calories
Needs (hunger, starvation, thirst, fatigue, etc.)
Definition: character.h:2219
int per_bonus
Definition: character.h:2100
time_point cached_time
Definition: character.h:1569
std::string custom_profession
Definition: character.h:566
int dex_bonus
Definition: character.h:2099
pimpl< pathfinding_settings > path_settings
Cache for pathfinding settings.
Definition: character.h:2161
std::array< int, num_hp_parts > damage_bandaged
Definition: character.h:1533
character_id id
Definition: character.h:2213
int healthy
How healthy the character is.
Definition: character.h:2104
int sleep_deprivation
Definition: character.h:2225
int int_cur
Definition: character.h:258
int int_max
Definition: character.h:253
int reactor_plut
Definition: character.h:1557
int fatigue
Definition: character.h:2224
std::array< int, num_bp > drench_capacity
Definition: character.h:2260
std::array< int, num_bp > temp_cur
Definition: character.h:2258
void initialize_stomach_contents()
Definition: stomach.cpp:195
std::array< int, num_hp_parts > healed_total
Definition: character.h:1743
void set_rad(int new_rad)
Definition: character.cpp:7035
int slow_rad
Definition: character.h:1558
int per_cur
Definition: character.h:259
int tank_plut
Definition: character.h:1556
int healthy_mod
Definition: character.h:2105
int dex_max
Definition: character.h:252
int thirst
Definition: character.h:2221
cata::optional< tripoint > next_expected_position
Definition: character.h:2235
int int_bonus
Definition: character.h:2101
std::array< int, num_hp_parts > damage_disinfected
Definition: character.h:1533
void set_anatomy(anatomy_id anat)
Definition: creature.cpp:1528
static const profession_id & generic()
Definition: profession.cpp:248
const time_point before_time_starts
A time point that is always before the current turn, even when the game has just started.
Definition: calendar.cpp:25
static constexpr nullopt_t nullopt
Definition: optional.h:22
static constexpr int BODYTEMP_NORM
Level 1 hotness.
Definition: weather.h:36

◆ Character() [3/3]

Character::Character ( Character &&  )
protecteddefault

Member Function Documentation

◆ absorb_hit()

void Character::absorb_hit ( const bodypart_id bp,
damage_instance dam 
)
overridevirtual

Runs through all bionics and armor on a part and reduces damage through their armor_absorb.

Implements Creature.

Definition at line 7980 of file character.cpp.

7981{
7982 std::list<item> worn_remains;
7983 bool armor_destroyed = false;
7984
7985 for( damage_unit &elem : dam.damage_units ) {
7986 if( elem.amount < 0 ) {
7987 // Prevents 0 damage hits (like from hallucinations) from ripping armor
7988 elem.amount = 0;
7989 continue;
7990 }
7991
7992 // The bio_ads CBM absorbs percentage melee damage and ranged damage (where possible) after armour.
7993 if( has_active_bionic( bio_ads ) && ( elem.amount > 0 ) && ( elem.type == DT_BASH ||
7994 elem.type == DT_CUT || elem.type == DT_STAB || elem.type == DT_BULLET ) ) {
7995 float elem_multi = 1;
7997 // HACK: Halves charge rate when hit for the next 3 turns, doesn't stack. See bionics.cpp for more information.
7998 bio.charge_timer = 6;
7999 // Bullet affected significantly more than stab, stab more than cut, cut more than bash.
8000 if( elem.type == DT_BASH ) {
8001 elem_multi = 0.8;
8002 } else if( elem.type == DT_CUT ) {
8003 elem_multi = 0.7;
8004 } else if( elem.type == DT_STAB ) {
8005 elem_multi = 0.55;
8006 } else if( elem.type == DT_BULLET ) {
8007 elem_multi = 0.25;
8008 }
8009 units::energy ads_cost = elem.amount * 500_J;
8010 if( bio.energy_stored >= ads_cost ) {
8011 dam.mult_damage( elem_multi );
8012 bio.energy_stored -= ads_cost;
8013 } else if( bio.energy_stored < ads_cost && bio.energy_stored != 0_kJ ) {
8014 // If you get hit and you lack energy it either deactivates, or deactivates and shorts out.
8015 // Either way you still get protection.
8016 dam.mult_damage( elem_multi );
8017 bio.energy_stored = 0_kJ;
8018 deactivate_bionic( bio );
8019 const units::energy shatter_thresh = ( elem.type == DT_BULLET ) ? 20_kJ : 15_kJ;
8020 if( ads_cost >= shatter_thresh ) {
8021 if( bio.incapacitated_time == 0_turns ) {
8022 add_msg_if_player( m_bad, _( "Your forcefield shatters and the feedback shorts out the %s!" ),
8023 bio.info().name );
8024 }
8025 int over = units::to_kilojoule( ads_cost - ( shatter_thresh - 5_kJ ) );
8026 bio.incapacitated_time += ( ( over / 5 ) ) * 1_turns;
8027 } else {
8028 add_msg_if_player( m_bad, _( "Your forcefield crackles and the %s powers down." ),
8029 bio.info().name );
8030 }
8031 } else {
8032 //You tried to (re)activate it and immediately enter combat, no mitigation for you.
8033 deactivate_bionic( bio );
8034 add_msg_if_player( m_bad, _( "The %s is interrupted and powers down." ), bio.info().name );
8035 }
8036 }
8037
8038 armor_enchantment_adjust( *this, elem );
8039
8040 // Only the outermost armor can be set on fire
8041 bool outermost = true;
8042 // The worn vector has the innermost item first, so
8043 // iterate reverse to damage the outermost (last in worn vector) first.
8044 for( auto iter = worn.rbegin(); iter != worn.rend(); ) {
8045 item &armor = *iter;
8046
8047 if( !armor.covers( bp->token ) ) {
8048 ++iter;
8049 continue;
8050 }
8051
8052 const std::string pre_damage_name = armor.tname();
8053 bool destroy = false;
8054
8055 item_armor_enchantment_adjust( *this, elem, armor );
8056 // Heat damage can set armor on fire
8057 // Even though it doesn't cause direct physical damage to it
8058 if( outermost && elem.type == DT_HEAT && elem.amount >= 1.0f ) {
8059 // TODO: Different fire intensity values based on damage
8060 fire_data frd{ 2 };
8061 destroy = armor.burn( frd );
8062 int fuel = roll_remainder( frd.fuel_produced );
8063 if( fuel > 0 ) {
8064 add_effect( effect_onfire, time_duration::from_turns( fuel + 1 ), bp->token, 0, false, true );
8065 }
8066 }
8067
8068 if( !destroy ) {
8069 destroy = armor_absorb( elem, armor );
8070 }
8071
8072 if( destroy ) {
8073 if( g->u.sees( *this ) ) {
8074 SCT.add( point( posx(), posy() ), direction::NORTH, remove_color_tags( pre_damage_name ),
8075 m_neutral, _( "destroyed" ), m_info );
8076 }
8077 destroyed_armor_msg( *this, pre_damage_name );
8078 armor_destroyed = true;
8079 armor.on_takeoff( *this );
8080 for( const item *it : armor.contents.all_items_top() ) {
8081 worn_remains.push_back( *it );
8082 }
8083 // decltype is the type name of the iterator, note that reverse_iterator::base returns the
8084 // iterator to the next element, not the one the revers_iterator points to.
8085 // http://stackoverflow.com/questions/1830158/how-to-call-erase-with-a-reverse-iterator
8086 iter = decltype( iter )( worn.erase( --( iter.base() ) ) );
8087 } else {
8088 ++iter;
8089 outermost = false;
8090 }
8091 }
8092
8093 passive_absorb_hit( bp, elem );
8094
8095 if( elem.type == DT_BASH ) {
8096 if( has_trait( trait_LIGHT_BONES ) ) {
8097 elem.amount *= 1.4;
8098 }
8099 if( has_trait( trait_HOLLOW_BONES ) ) {
8100 elem.amount *= 1.8;
8101 }
8102 }
8103
8104 elem.amount = std::max( elem.amount, 0.0f );
8105 }
8106 map &here = get_map();
8107 for( item &remain : worn_remains ) {
8108 here.add_item_or_charges( pos(), remain );
8109 }
8110 if( armor_destroyed ) {
8112 }
8113}
static const trait_id trait_HOLLOW_BONES("HOLLOW_BONES")
static void destroyed_armor_msg(Character &who, const std::string &pre_damage_name)
Definition: character.cpp:7890
static const bionic_id bio_ads("bio_ads")
static void item_armor_enchantment_adjust(const Character &guy, damage_unit &du, const item &armor)
Definition: character.cpp:7904
static const trait_id trait_LIGHT_BONES("LIGHT_BONES")
static void armor_enchantment_adjust(const Character &guy, damage_unit &du)
Definition: character.cpp:7944
static const efftype_id effect_onfire("onfire")
bionic & get_bionic_state(const bionic_id &id)
Get state of bionic with given id.
Definition: character.cpp:1784
int posx() const override
Definition: character.h:786
int posy() const override
Definition: character.h:789
std::list< item > worn
Definition: character.h:1532
bool armor_absorb(damage_unit &du, item &armor)
Reduces and mutates du, prints messages about armor taking damage.
Definition: character.cpp:8115
void drop_invalid_inventory()
Definition: character.cpp:3159
void passive_absorb_hit(const bodypart_id &bp, damage_unit &du) const
Check for relevant passive, non-clothing that can absorb damage, and reduce by specified damage unit.
Definition: character.cpp:7871
const tripoint & pos() const override
Definition: character.cpp:587
bool deactivate_bionic(bionic &bio, bool eff_only=false)
Handles bionic deactivation effects of the entered bionic, returns if anything deactivated.
Definition: bionics.cpp:1065
bool has_trait(const trait_id &b) const override
Returns true if the player has the entered trait.
Definition: mutation.cpp:103
bool has_active_bionic(const bionic_id &b) const
Returns true if the player has the entered bionic id and it is powered on.
Definition: character.cpp:1805
void add_effect(const effect &eff, bool force=false, bool deferred=false)
Definition: creature.cpp:986
virtual void add_msg_if_player(const std::string &) const
Definition: creature.h:597
std::list< item * > all_items_top()
returns a list of pointers to all top-level items
Definition: item.h:211
item_contents contents
Definition: item.h:2158
std::string tname(unsigned int quantity=1, bool with_prefix=true, unsigned int truncate=0) const
Return the (translated) item name.
Definition: item.cpp:4546
void on_takeoff(Character &p)
Callback when a character takes off an item.
Definition: item.cpp:4387
bool burn(fire_data &frd)
Burns the item.
Definition: item.cpp:8284
bool covers(body_part bp) const
Whether this item (when worn) covers the given body part.
Definition: item.cpp:743
Manage and cache data about a part of the map.
Definition: map.h:384
item & add_item_or_charges(const tripoint &pos, item obj, bool overflow=true)
Adds an item to map tile or stacks charges.
Definition: map.cpp:4236
void add(const point &pos, direction p_oDir, const std::string &p_sText, game_message_type p_gmt, const std::string &p_sText2="", game_message_type p_gmt2=m_neutral, const std::string &p_sType="")
Definition: output.cpp:1757
static constexpr time_duration from_turns(const T t)
Named constructors to get a duration representing a multiple of the named time units.
Definition: calendar.h:204
@ DT_STAB
Definition: damage.h:27
@ DT_BASH
Definition: damage.h:24
@ DT_CUT
Definition: damage.h:25
@ DT_BULLET
Definition: damage.h:31
@ DT_HEAT
Definition: damage.h:28
@ m_neutral
Definition: enums.h:267
@ m_info
Definition: enums.h:265
@ m_bad
Definition: enums.h:261
std::unique_ptr< game > g
Definition: game.cpp:281
map & get_map()
Definition: map.cpp:146
constexpr value_type to_kilojoule(const quantity< value_type, energy_in_joule_tag > &v)
Definition: units_energy.h:46
std::string remove_color_tags(const std::string &s)
Removes the color tags from the input string.
Definition: output.cpp:145
scrollingcombattext SCT
Definition: output.cpp:65
int roll_remainder(double value)
Definition: rng.cpp:96
translation name
Definition: bionics.h:34
const bionic_data & info() const
Definition: bionics.h:170
int charge_timer
Definition: bionics.h:153
units::energy energy_stored
Definition: bionics.h:163
time_duration incapacitated_time
Definition: bionics.h:161
std::vector< damage_unit > damage_units
Definition: damage.h:52
void mult_damage(double multiplier, bool pre_armor=false)
Definition: damage.cpp:48
float amount
Definition: damage.h:37
damage_type type
Definition: damage.h:36
Contains the state of a fire in one tile on one turn.
Definition: fire.h:18
Definition: point.h:35
#define _(msg)
Definition: translations.h:116

References _, scrollingcombattext::add(), Creature::add_effect(), map::add_item_or_charges(), Creature::add_msg_if_player(), item_contents::all_items_top(), damage_unit::amount, armor_absorb(), armor_enchantment_adjust(), bio_ads, item::burn(), bionic::charge_timer, item::contents, item::covers(), damage_instance::damage_units, deactivate_bionic(), destroyed_armor_msg(), drop_invalid_inventory(), DT_BASH, DT_BULLET, DT_CUT, DT_HEAT, DT_STAB, effect_onfire, bionic::energy_stored, time_duration::from_turns(), g, get_bionic_state(), get_map(), has_active_bionic(), has_trait(), bionic::incapacitated_time, bionic::info(), item_armor_enchantment_adjust(), m_bad, m_info, m_neutral, damage_instance::mult_damage(), bionic_data::name, NORTH, item::on_takeoff(), passive_absorb_hit(), pos(), posx(), posy(), remove_color_tags(), roll_remainder(), SCT, item::tname(), units::to_kilojoule(), trait_HOLLOW_BONES, trait_LIGHT_BONES, damage_unit::type, and worn.

◆ action_taken()

void Character::action_taken ( )

Called after every action, invalidates player caches.

Definition at line 798 of file character.cpp.

799{
800 nv_cached = false;
801}
bool nv_cached
Definition: character.h:1534

References nv_cached.

Referenced by game::do_turn().

◆ activate_bionic()

bool Character::activate_bionic ( bionic bio,
bool  eff_only = false 
)

Handles bionic activation effects of the entered bionic, returns if anything activated.

Definition at line 532 of file bionics.cpp.

533{
534 const bool mounted = is_mounted();
535 if( bio.incapacitated_time > 0_turns ) {
536 add_msg_if_player( m_info, _( "Your %s is shorting out and can't be activated." ),
537 bio.info().name );
538 return false;
539 }
540
541 // eff_only means only do the effect without messing with stats or displaying messages
542 if( !eff_only ) {
543 if( bio.powered ) {
544 // It's already on!
545 return false;
546 }
547 if( !enough_power_for( bio.id ) ) {
548 add_msg_if_player( m_info, _( "You don't have the power to activate your %s." ),
549 bio.info().name );
550 return false;
551 }
552
553 // HACK: burn_fuel() doesn't check for available fuel in remote source on start.
554 // If CBM is successfully activated, the check will occur when it actually tries to draw power
555 if( !bio.info().is_remote_fueled ) {
556 if( !burn_fuel( bio, true ) ) {
557 return false;
558 }
559 }
560
561 // We can actually activate now, do activation-y things
563
564 bio.powered = bio.info().has_flag( flag_BIONIC_TOGGLED ) || bio.info().charge_time > 0;
565
566 if( bio.info().charge_time > 0 ) {
567 bio.charge_timer = bio.info().charge_time;
568 }
569 if( !bio.id->enchantments.empty() ) {
571 }
572 }
573
574 auto add_msg_activate = [&]() {
575 if( !eff_only && !bio.is_auto_start_keep_full() ) {
576 add_msg_if_player( m_info, _( "You activate your %s." ), bio.info().name );
577 }
578 };
579 auto refund_power = [&]() {
580 if( !eff_only ) {
582 }
583 };
584
585 item tmp_item;
586 const w_point &weatherPoint = get_weather().get_precise();
587
588 map &here = get_map();
589 // On activation effects go here
590 if( bio.info().has_flag( flag_BIONIC_GUN ) ) {
591 add_msg_activate();
592 refund_power(); // Power usage calculated later, in avatar_action::fire
594 bio.info().power_activate );
595 } else if( bio.info().has_flag( flag_BIONIC_WEAPON ) ) {
597 add_msg_if_player( m_info, _( "Deactivate your %s first!" ), weapon.tname() );
598 refund_power();
599 bio.powered = false;
600 return false;
601 }
602
603 if( !weapon.is_null() ) {
604 const std::string query = string_format( _( "Stop wielding %s?" ), weapon.tname() );
605 if( !dispose_item( item_location( *this, &weapon ), query ) ) {
606 refund_power();
607 bio.powered = false;
608 return false;
609 }
610 }
611
612 add_msg_activate();
613 weapon = item( bio.info().fake_item );
614 weapon.invlet = '#';
615 if( bio.ammo_count > 0 ) {
618 }
619 } else if( bio.id == bio_ears && has_active_bionic( bio_earplugs ) ) {
620 add_msg_activate();
621 for( bionic &bio : *my_bionics ) {
622 if( bio.id == bio_earplugs ) {
623 bio.powered = false;
624 add_msg_if_player( m_info, _( "Your %s automatically turn off." ),
625 bio.info().name );
626 }
627 }
628 } else if( bio.id == bio_earplugs && has_active_bionic( bio_ears ) ) {
629 add_msg_activate();
630 for( bionic &bio : *my_bionics ) {
631 if( bio.id == bio_ears ) {
632 bio.powered = false;
633 add_msg_if_player( m_info, _( "Your %s automatically turns off." ),
634 bio.info().name );
635 }
636 }
637 } else if( bio.id == bio_evap ) {
638 add_msg_activate();
639 const w_point &weatherPoint = get_weather().get_precise();
640 int humidity = get_local_humidity( weatherPoint.humidity, get_weather().weather_id,
641 g->is_sheltered( g->u.pos() ) );
642 // thirst units = 5 mL
643 int water_available = std::lround( humidity * 3.0 / 100.0 );
644 if( water_available == 0 ) {
645 bio.powered = false;
646 add_msg_if_player( m_bad, _( "There is not enough humidity in the air for your %s to function." ),
647 bio.info().name );
648 return false;
649 } else if( water_available == 1 ) {
651 _( "Your %s issues a low humidity warning. Efficiency will be reduced." ),
652 bio.info().name );
653 }
654 } else if( bio.id == bio_tools ) {
655 add_msg_activate();
657 } else if( bio.id == bio_cqb ) {
658 add_msg_activate();
659 const avatar *you = as_avatar();
660 if( you && !martial_arts_data->pick_style( *you ) ) {
661 bio.powered = false;
662 add_msg_if_player( m_info, _( "You change your mind and turn it off." ) );
663 return false;
664 }
665 } else if( bio.id == bio_resonator ) {
666 add_msg_activate();
667 //~Sound of a bionic sonic-resonator shaking the area
668 sounds::sound( pos(), 30, sounds::sound_t::combat, _( "VRRRRMP!" ), false, "bionic",
669 static_cast<std::string>( bio_resonator ) );
670 for( const tripoint &bashpoint : here.points_in_radius( pos(), 1 ) ) {
671 here.bash( bashpoint, 110 );
672 // Multibash effect, so that doors &c will fall
673 here.bash( bashpoint, 110 );
674 here.bash( bashpoint, 110 );
675 }
676
677 mod_moves( -100 );
678 } else if( bio.id == bio_time_freeze ) {
679 if( mounted ) {
680 refund_power();
681 add_msg_if_player( m_info, _( "You cannot activate %s while mounted." ), bio.info().name );
682 return false;
683 }
684 add_msg_activate();
685
687 set_power_level( 0_kJ );
688 add_msg_if_player( m_good, _( "Your speed suddenly increases!" ) );
689 if( one_in( 3 ) ) {
690 add_msg_if_player( m_bad, _( "Your muscles tear with the strain." ) );
691 apply_damage( nullptr, bodypart_id( "arm_l" ), rng( 5, 10 ) );
692 apply_damage( nullptr, bodypart_id( "arm_r" ), rng( 5, 10 ) );
693 apply_damage( nullptr, bodypart_id( "leg_l" ), rng( 7, 12 ) );
694 apply_damage( nullptr, bodypart_id( "leg_r" ), rng( 7, 12 ) );
695 apply_damage( nullptr, bodypart_id( "torso" ), rng( 5, 15 ) );
696 }
697 if( one_in( 5 ) ) {
698 add_effect( effect_teleglow, rng( 5_minutes, 40_minutes ) );
699 }
700 } else if( bio.id == bio_teleport ) {
701 if( mounted ) {
702 refund_power();
703 add_msg_if_player( m_info, _( "You cannot activate %s while mounted." ), bio.info().name );
704 return false;
705 }
706 add_msg_activate();
707
708 teleport::teleport( *this );
709 add_effect( effect_teleglow, 30_minutes );
710 mod_moves( -100 );
711 } else if( bio.id == bio_blood_anal ) {
712 add_msg_activate();
714 } else if( bio.id == bio_blood_filter ) {
715 add_msg_activate();
716 static const std::vector<efftype_id> removable = {{
724 }
725 };
726
727 for( const auto &eff : removable ) {
728 remove_effect( eff );
729 }
730 // Purging the substance won't remove the fatigue it caused
733 set_painkiller( 0 );
734 set_stim( 0 );
735 mod_moves( -100 );
736 } else if( bio.id == bio_torsionratchet ) {
737 add_msg_activate();
738 add_msg_if_player( m_info, _( "Your torsion ratchet locks onto your joints." ) );
739 } else if( bio.id == bio_jointservo ) {
740 add_msg_activate();
741 add_msg_if_player( m_info, _( "You can now run faster, assisted by joint servomotors." ) );
742 } else if( bio.id == bio_lighter ) {
743 const cata::optional<tripoint> pnt = choose_adjacent( _( "Start a fire where?" ) );
744 if( pnt && here.is_flammable( *pnt ) ) {
745 add_msg_activate();
746 here.add_field( *pnt, fd_fire, 1 );
747 mod_moves( -100 );
748 } else {
749 refund_power();
750 add_msg_if_player( m_info, _( "There's nothing to light there." ) );
751 return false;
752 }
753 } else if( bio.id == bio_geiger ) {
754 add_msg_activate();
755 add_msg_if_player( m_info, _( "Your radiation level: %d" ), get_rad() );
756 } else if( bio.id == bio_radscrubber ) {
757 add_msg_activate();
758 if( get_rad() > 4 ) {
759 mod_rad( -5 );
760 } else {
761 set_rad( 0 );
762 }
763 } else if( bio.id == bio_adrenaline ) {
764 add_msg_activate();
766 add_msg_if_player( m_bad, _( "Safeguards kick in, and the bionic refuses to activate!" ) );
767 refund_power();
768 return false;
769 } else {
770 add_msg_activate();
771 add_effect( effect_adrenaline, 20_minutes );
772 }
773 } else if( bio.id == bio_emp ) {
774 if( const cata::optional<tripoint> pnt = choose_adjacent( _( "Create an EMP where?" ) ) ) {
775 add_msg_activate();
777 mod_moves( -100 );
778 } else {
779 refund_power();
780 return false;
781 }
782 } else if( bio.id == bio_hydraulics ) {
783 add_msg_activate();
784 add_msg_if_player( m_good, _( "Your muscles hiss as hydraulic strength fills them!" ) );
785 //~ Sound of hissing hydraulic muscle! (not quite as loud as a car horn)
786 sounds::sound( pos(), 19, sounds::sound_t::activity, _( "HISISSS!" ), false, "bionic",
787 static_cast<std::string>( bio_hydraulics ) );
788 } else if( bio.id == bio_water_extractor ) {
789 bool no_target = true;
790 bool extracted = false;
791 for( item &it : here.i_at( pos() ) ) {
792 static const auto volume_per_water_charge = 500_ml;
793 if( it.is_corpse() ) {
794 const int avail = it.get_var( "remaining_water", it.volume() / volume_per_water_charge );
795 if( avail > 0 ) {
796 no_target = false;
797 if( query_yn( _( "Extract water from the %s" ),
798 colorize( it.tname(), it.color_in_inventory() ) ) ) {
799 item water( itype_water_clean, calendar::turn, avail );
800 if( liquid_handler::consume_liquid( water ) ) {
801 add_msg_activate();
802 extracted = true;
803 it.set_var( "remaining_water", static_cast<int>( water.charges ) );
804 }
805 break;
806 }
807 }
808 }
809 }
810 if( no_target ) {
811 add_msg_if_player( m_bad, _( "There is no suitable corpse on this tile." ) );
812 }
813 if( !extracted ) {
814 refund_power();
815 return false;
816 }
817 } else if( bio.id == bio_magnet ) {
818 add_msg_activate();
819 static const std::set<material_id> affected_materials =
820 { material_id( "iron" ), material_id( "steel" ) };
821 // Remember all items that will be affected, then affect them
822 // Don't "snowball" by affecting some items multiple times
823 std::vector<std::pair<item, tripoint>> affected;
824 const units::mass weight_cap = weight_capacity();
825 for( const tripoint &p : here.points_in_radius( pos(), 10 ) ) {
826 if( p == pos() || !here.has_items( p ) || here.has_flag( flag_SEALED, p ) ) {
827 continue;
828 }
829
830 map_stack stack = here.i_at( p );
831 for( auto it = stack.begin(); it != stack.end(); it++ ) {
832 if( it->weight() < weight_cap &&
833 it->made_of_any( affected_materials ) ) {
834 affected.emplace_back( std::make_pair( *it, p ) );
835 stack.erase( it );
836 break;
837 }
838 }
839 }
840
841 for( const std::pair<item, tripoint> &pr : affected ) {
842 projectile proj;
843 proj.speed = 50;
844 proj.impact = damage_instance::physical( pr.first.weight() / 250_gram, 0, 0, 0 );
845 // make the projectile stop one tile short to prevent hitting the player
846 proj.range = rl_dist( pr.second, pos() ) - 1;
847 static const std::set<ammo_effect_str_id> ammo_effects = {{
848 ammo_effect_str_id( "NO_ITEM_DAMAGE" ),
849 ammo_effect_str_id( "DRAW_AS_LINE" ),
850 ammo_effect_str_id( "NO_DAMAGE_SCALING" ),
851 ammo_effect_str_id( "JET" ),
852 }
853 };
854 for( const auto &eff : ammo_effects ) {
855 proj.add_effect( eff );
856 }
857
859 proj, pr.second, pos(), dispersion_sources{ 0 }, this );
860 here.add_item_or_charges( dealt.end_point, pr.first );
861 }
862
863 mod_moves( -100 );
864 } else if( bio.id == bio_lockpick ) {
865 bool used = false;
866 bool tried_lockpick = false;
867 const cata::optional<tripoint> pnt = choose_adjacent( _( "Use your lockpick where?" ) );
868 std::string open_message;
869 if( pnt ) {
870 tried_lockpick = true;
871 ter_id ter_type = g->m.ter( *pnt );
872 furn_id furn_type = g->m.furn( *pnt );
873 lockpicking_open_result lr = get_lockpicking_open_result( ter_type, furn_type );
874 ter_id new_ter_type = lr.new_ter_type;
875 furn_id new_furn_type = lr.new_furn_type;
876 open_message = lr.open_message;
877
878 if( new_ter_type != t_null || new_furn_type != f_null ) {
879 g->m.has_furn( *pnt ) ?
880 g->m.furn_set( *pnt, new_furn_type ) :
881 static_cast<void>( g->m.ter_set( *pnt, new_ter_type ) );
882 used = true;
883 }
884 }
885
886 if( used ) {
887 add_msg_activate();
888 add_msg_if_player( m_good, open_message );
889 mod_moves( -100 );
890 } else {
891 refund_power();
892 if( tried_lockpick ) {
893 add_msg_if_player( m_info, _( "There is nothing to lockpick nearby." ) );
894 }
895 return false;
896 }
897 } else if( bio.id == bio_flashbang ) {
898 add_msg_activate();
899 explosion_handler::flashbang( pos(), true, "explosion" );
900 mod_moves( -100 );
901 } else if( bio.id == bio_shockwave ) {
902 add_msg_activate();
903
905 sw.affects_player = false;
906 sw.radius = 3;
907 sw.force = 4;
908 sw.stun = 2;
909 sw.dam_mult = 8;
910 // affects_player is always false, so assuming the player is always the source of this
911 explosion_handler::shockwave( pos(), sw, "explosion", &get_player_character() );
912 add_msg_if_player( m_neutral, _( "You unleash a powerful shockwave!" ) );
913 mod_moves( -100 );
914 } else if( bio.id == bio_meteorologist ) {
916 add_msg_activate();
917 // Calculate local wind power
918 int vehwindspeed = 0;
919 if( optional_vpart_position vp = here.veh_at( pos() ) ) {
920 // vehicle velocity in mph
921 vehwindspeed = std::abs( vp->vehicle().velocity / 100 );
922 }
923 const oter_id &cur_om_ter = overmap_buffer.ter( global_omt_location() );
924 /* cache g->get_temperature( player location ) since it is used twice. No reason to recalc */
925 const auto player_local_temp = weather.get_temperature( g->u.pos() );
926 /* windpower defined in internal velocity units (=.01 mph) */
927 double windpower = 100.0f * get_local_windpower( weather.windspeed + vehwindspeed,
928 cur_om_ter, pos(), weather.winddirection, g->is_sheltered( pos() ) );
929 add_msg_if_player( m_info, _( "Temperature: %s." ), print_temperature( player_local_temp ) );
930 add_msg_if_player( m_info, _( "Relative Humidity: %s." ),
932 get_local_humidity( weatherPoint.humidity, weather.weather_id,
933 g->is_sheltered( g->u.pos() ) ) ) );
934 add_msg_if_player( m_info, _( "Pressure: %s." ),
935 print_pressure( static_cast<int>( weatherPoint.pressure ) ) );
936 add_msg_if_player( m_info, _( "Wind Speed: %.1f %s." ),
937 convert_velocity( static_cast<int>( windpower ), VU_WIND ),
939 add_msg_if_player( m_info, _( "Feels Like: %s." ),
942 weatherPoint.humidity,
943 windpower / 100 ) + player_local_temp ) );
944 std::string dirstring = get_dirstring( weather.winddirection );
945 add_msg_if_player( m_info, _( "Wind Direction: From the %s." ), dirstring );
946 } else if( bio.id == bio_remote ) {
947 add_msg_activate();
948 int choice = uilist( _( "Perform which function:" ), {
949 _( "Control vehicle" ), _( "RC radio" )
950 } );
951 if( choice >= 0 && choice <= 1 ) {
952 item ctr;
953 if( choice == 0 ) {
954 ctr = item( "remotevehcontrol", calendar::start_of_cataclysm );
955 } else {
956 ctr = item( "radiocontrol", calendar::start_of_cataclysm );
957 }
959 int power_use = invoke_item( &ctr );
960 mod_power_level( units::from_kilojoule( -power_use ) );
961 bio.powered = ctr.active;
962 } else {
963 bio.powered = g->remoteveh() != nullptr || !get_value( "remote_controlling" ).empty();
964 }
965 } else if( bio.id == bio_plutdump ) {
966 if( query_yn(
967 _( "WARNING: Purging all fuel is likely to result in radiation! Purge anyway?" ) ) ) {
968 add_msg_activate();
970 tank_plut = 0;
971 reactor_plut = 0;
972 } else {
973 refund_power();
974 return false;
975 }
976 } else if( bio.info().is_remote_fueled ) {
977 std::vector<item *> cables = items_with( []( const item & it ) {
978 return it.has_flag( flag_CABLE_SPOOL );
979 } );
980 bool has_cable = !cables.empty();
981 bool free_cable = false;
982 bool success = false;
983 if( !has_cable ) {
985 _( "You need a jumper cable connected to a power source to drain power from it." ) );
986 } else {
987 for( item *cable : cables ) {
988 const std::string state = cable->get_var( "state" );
989 if( state == "cable_charger" ) {
991 _( "Cable is plugged-in to the CBM but it has to be also connected to the power source." ) );
992 }
993 if( state == "cable_charger_link" ) {
994 add_msg_activate();
995 success = true;
997 _( "You are plugged to the vehicle. It will charge you if it has some juice in it." ) );
998 }
999 if( state == "solar_pack_link" ) {
1000 add_msg_activate();
1001 success = true;
1003 _( "You are plugged to a solar pack. It will charge you if it's unfolded and in sunlight." ) );
1004 }
1005 if( state == "UPS_link" ) {
1006 add_msg_activate();
1007 success = true;
1009 _( "You are plugged to a UPS. It will charge you if it has some juice in it." ) );
1010 }
1011 if( state == "solar_pack" || state == "UPS" ) {
1013 _( "You have a cable plugged to a portable power source, but you need to plug it in to the CBM." ) );
1014 }
1015 if( state == "pay_out_cable" ) {
1017 _( "You have a cable plugged to a vehicle, but you need to plug it in to the CBM." ) );
1018 }
1019 if( state == "attach_first" ) {
1020 free_cable = true;
1021 }
1022 }
1023
1024 if( free_cable ) {
1026 _( "You have at least one free cable in your inventory that you could use to plug yourself in." ) );
1027 }
1028 }
1029 if( !success ) {
1030 refund_power();
1031 bio.powered = false;
1032 return false;
1033 }
1034
1035 } else if( bio.id == bio_probability_travel ) {
1036 if( const cata::optional<tripoint> pnt = choose_adjacent( _( "Tunnel in which direction?" ) ) ) {
1037 if( g->m.impassable( *pnt ) ) {
1038 add_msg_activate();
1039 g->phasing_move( *pnt );
1040 } else {
1041 refund_power();
1042 add_msg_if_player( m_info, _( "There's nothing to phase through there." ) );
1043 return false;
1044 }
1045 } else {
1046 refund_power();
1047 return false;
1048 }
1049 } else {
1050 add_msg_activate();
1051 }
1052
1053 // Recalculate stats (strength, mods from pain etc.) that could have been affected
1055 reset();
1056
1057 // Also reset crafting inventory cache if this bionic spawned a fake item
1058 if( !bio.info().fake_item.is_empty() ) {
1060 }
1061
1062 return true;
1063}
cata::optional< tripoint > choose_adjacent(const std::string &message, const bool allow_vertical)
Request player input of adjacent tile, possibly including vertical tiles.
Definition: action.cpp:1026
units::quantity< V, B > rng(const units::quantity< V, B > &min, const units::quantity< V, B > &max)
Definition: artifact.cpp:32
dealt_projectile_attack projectile_attack(const projectile &proj_arg, const tripoint &source, const tripoint &target_arg, const dispersion_sources &dispersion, Creature *origin, const vehicle *in_veh)
Fires a projectile at the target point from the source point with total_dispersion dispersion.
Definition: ballistics.cpp:201
static const flag_str_id flag_BIONIC_WEAPON("BIONIC_WEAPON")
static const bionic_id bio_cqb("bio_cqb")
static const bionic_id bio_geiger("bio_geiger")
static const itype_id itype_water_clean("water_clean")
static const efftype_id effect_bloodworms("bloodworms")
static const flag_str_id flag_BIONIC_GUN("BIONIC_GUN")
static const efftype_id effect_weed_high("weed_high")
static const efftype_id effect_fungus("fungus")
static const efftype_id effect_pkill_l("pkill_l")
static const efftype_id effect_took_prozac("took_prozac")
static const efftype_id effect_datura("datura")
static const efftype_id effect_drunk("drunk")
static const efftype_id effect_teleglow("teleglow")
static const efftype_id effect_badpoison("badpoison")
static const efftype_id effect_dermatik("dermatik")
static const std::string flag_NO_UNWIELD("NO_UNWIELD")
static const efftype_id effect_pkill2("pkill2")
static const efftype_id effect_adrenaline("adrenaline")
static void force_comedown(effect &eff)
Definition: bionics.cpp:443
static const bionic_id bio_evap("bio_evap")
static const efftype_id effect_took_flumed("took_flumed")
static const bionic_id bio_plutdump("bio_plutdump")
static const efftype_id effect_hallu("hallu")
static const efftype_id effect_pblue("pblue")
static const bionic_id bio_water_extractor("bio_water_extractor")
static const bionic_id bio_hydraulics("bio_hydraulics")
static const efftype_id effect_cocaine_high("cocaine_high")
static const bionic_id bio_lighter("bio_lighter")
static const bionic_id bio_magnet("bio_magnet")
static const efftype_id effect_meth("meth")
static const bionic_id bio_flashbang("bio_flashbang")
static const bionic_id bio_time_freeze("bio_time_freeze")
static const bionic_id bio_meteorologist("bio_meteorologist")
static const std::string flag_CABLE_SPOOL("CABLE_SPOOL")
static const efftype_id effect_visuals("visuals")
static const bionic_id bio_ears("bio_ears")
static const bionic_id bio_shockwave("bio_shockwave")
static const bionic_id bio_emp("bio_emp")
static const bionic_id bio_remote("bio_remote")
static const efftype_id effect_stung("stung")
static const std::string flag_SEALED("SEALED")
static const flag_str_id flag_BIONIC_TOGGLED("BIONIC_TOGGLED")
static const efftype_id effect_cig("cig")
static const bionic_id bio_tools("bio_tools")
static const bionic_id bio_earplugs("bio_earplugs")
static const bionic_id bio_adrenaline("bio_adrenaline")
static const bionic_id bio_lockpick("bio_lockpick")
static const bionic_id bio_blood_anal("bio_blood_anal")
static const bionic_id bio_probability_travel("bio_probability_travel")
static const bionic_id bio_radscrubber("bio_radscrubber")
static const bionic_id bio_teleport("bio_teleport")
static const efftype_id effect_poison("poison")
static const bionic_id bio_resonator("bio_resonator")
static const bionic_id bio_blood_filter("bio_blood_filter")
static const efftype_id effect_pkill1("pkill1")
static const efftype_id effect_took_xanax("took_xanax")
static const efftype_id effect_pkill3("pkill3")
static const efftype_id effect_took_prozac_bad("took_prozac_bad")
static const bionic_id bio_torsionratchet("bio_torsionratchet")
static const efftype_id effect_iodine("iodine")
static const bionic_id bio_jointservo("bio_jointservo")
int_id< body_part_type > bodypart_id
Definition: bodypart.h:23
Character & get_player_character()
Definition: character.cpp:393
units::mass weight_capacity() const override
Definition: character.cpp:2595
void conduct_blood_analysis() const
Definition: character.cpp:1942
void mod_power_level(const units::energy &npower)
Definition: character.cpp:1905
void mod_rad(int mod)
Definition: character.cpp:7040
pimpl< character_martial_arts > martial_arts_data
Definition: character.h:1550
bool query_yn(const char *const msg, Args &&... args) const
It is supposed to hide the query_yn to simplify player vs.
Definition: character.h:1460
pimpl< bionic_collection > my_bionics
Definition: character.h:1549
virtual bool invoke_item(item *, const tripoint &pt)
Asks how to use the item (if it has more than one use_method) and uses it.
Definition: character.cpp:7186
bool burn_fuel(bionic &bio, bool start=false)
Convert fuel to bionic power.
Definition: bionics.cpp:1153
void set_power_level(const units::energy &npower)
Definition: character.cpp:1895
void set_painkiller(int npkill)
Sets intensity of painkillers
Definition: character.cpp:9744
bool is_mounted() const
Definition: character.cpp:1064
void apply_damage(Creature *source, bodypart_id hurt, int dam, bool bypass_med=false) override
Actually hurt the player, hurts a body_part directly, no armor reduction.
Definition: character.cpp:8358
bool enough_power_for(const bionic_id &bid) const
Definition: character.cpp:1937
void recalculate_enchantment_cache()
Definition: character.cpp:7813
int get_rad() const
Definition: character.cpp:7030
virtual bool dispose_item(item_location &&obj, const std::string &prompt=std::string())
Drop, wear, stash or otherwise try to dispose of an item consuming appropriate moves.
Definition: character.cpp:7225
void reset() override
Handles stat and bonus reset.
Definition: character.cpp:3610
void reset_encumbrance()
Recalculates encumbrance cache.
Definition: character.cpp:3631
units::energy get_power_level() const
Definition: character.cpp:1885
item weapon
Definition: character.h:1546
tripoint_abs_omt global_omt_location() const
Returns the location of the player in global overmap terrain coordinates.
Definition: character.cpp:6231
void invalidate_crafting_inventory()
Definition: crafting.cpp:596
std::string get_value(const std::string &key) const
Definition: creature.cpp:1347
bool has_effect(const efftype_id &eff_id, body_part bp=num_bp) const
Check if creature has the matching effect.
Definition: creature.cpp:1185
bool remove_effect(const efftype_id &eff_id, body_part bp=num_bp)
Removes a listed effect.
Definition: creature.cpp:1142
void mod_moves(int nmoves)
Definition: creature.cpp:1414
const effect & get_effect(const efftype_id &eff_id, body_part bp=num_bp) const
Return the effect that matches the given arguments exactly.
Definition: creature.cpp:1225
virtual avatar * as_avatar()
Definition: creature.h:128
Definition: avatar.h:55
A lightweight handle to an item independent of it's location Unlike a raw pointer can be (de-)seriali...
Definition: item_location.h:23
iterator begin()
Definition: item_stack.cpp:28
iterator end()
Definition: item_stack.cpp:33
bool active
Definition: item.h:2234
bool is_null() const
Definition: item.cpp:732
item & ammo_set(const itype_id &ammo, int qty=-1)
Filter setting the ammo for this instance Any existing ammo is removed.
Definition: item.cpp:590
int charges
Definition: item.h:2196
bool has_flag(const std::string &flag) const
Definition: item.cpp:5308
char invlet
Definition: item.h:2233
Definition: map.h:105
iterator erase(const_iterator it) override
Definition: map.cpp:152
bash_results bash(const tripoint &p, int str, bool silent=false, bool destroy=false, bool bash_floor=false, const vehicle *bashing_vehicle=nullptr)
Returns a pair where first is whether anything was smashed and second is if it was destroyed.
Definition: map.cpp:3527
bool has_flag(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2293
bool add_field(const tripoint &p, const field_type_id &type_id, int intensity=INT_MAX, const time_duration &age=0_turns, bool hit_player=true)
Add field entry at point, or set intensity if present.
Definition: map.cpp:5411
tripoint_range< tripoint > points_in_radius(const tripoint &center, size_t radius, size_t radiusz=0) const
Definition: map.cpp:8621
map_stack i_at(const tripoint &p)
Definition: map.cpp:4091
bool is_flammable(const tripoint &p)
Returns true if there is a flammable item or field or the furn/terrain is flammable at p.
Definition: map.cpp:2653
optional_vpart_position veh_at(const tripoint &p) const
Checks if tile is occupied by vehicle and by which part.
Definition: map.cpp:1009
bool has_items(const tripoint &p) const
Checks for existence of items.
Definition: map.cpp:4772
Simple wrapper to forward functions that may return a cata::optional to vpart_position.
const oter_id & ter(const tripoint_abs_omt &p)
Returns the overmap terrain at the given OMT coordinates.
bool is_empty() const
Returns whether this id is empty.
Definition: string_id.h:298
uilist: scrolling vertical list menu
Definition: ui.h:187
std::vector< item * > items_with(const std::function< bool(const item &)> &filter)
Returns all items (including those within a container) matching the filter.
Definition: visitable.cpp:324
const w_point & get_precise() const
Definition: weather.h:218
std::string colorize(const std::string &text, const nc_color &color)
Definition: color.cpp:669
int rl_dist(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:519
@ m_good
Definition: enums.h:260
@ m_mixed
Definition: enums.h:262
field_type_id fd_fire
Definition: field_type.cpp:345
double get_local_windpower(double windpower, const oter_id &omter, const tripoint &location, const int &winddirection, bool sheltered)
Definition: weather.cpp:938
int get_local_humidity(double humidity, const weather_type_id &weather, bool sheltered)
Definition: weather.cpp:924
std::string print_temperature(double fahrenheit, int decimals)
Print temperature (and convert to Celsius if Celsius display is enabled.)
Definition: weather.cpp:717
std::string get_dirstring(int angle)
Definition: weather.cpp:874
weather_manager & get_weather()
Definition: weather.cpp:64
std::string print_pressure(double pressure, int decimals)
Print pressure (no conversions.)
Definition: weather.cpp:752
std::string print_humidity(double humidity, int decimals)
Print relative humidity (no conversions.)
Definition: weather.cpp:743
int get_local_windchill(double temperature_f, double humidity, double wind_mph)
Definition: weather.cpp:797
string_id< ammo_effect > ammo_effect_str_id
Definition: map.cpp:103
lockpicking_open_result get_lockpicking_open_result(ter_id ter_type, furn_id furn_type)
Gets lockpicked object and message.
Definition: mapdata.cpp:1062
ter_id t_null
Definition: mapdata.cpp:625
furn_id f_null
Definition: mapdata.cpp:1097
void fire_wielded_weapon(avatar &you)
Checks if the wielded weapon is a gun and can be fired then starts interactive aiming.
void fire_ranged_bionic(avatar &you, const item &fake_gun, const units::energy &cost_per_shot)
Stores fake gun specified by the bionic and starts interactive aiming.
@ success
Definition: behavior.h:20
const time_point & start_of_cataclysm
Definition: calendar.cpp:33
time_point turn
Definition: calendar.cpp:36
void shockwave(const tripoint &p, const shockwave_data &sw, const std::string &exp_name, Creature *source)
Shockwave applies knockback with given parameters to all targets within radius of p.
Definition: explosion.cpp:954
void flashbang(const tripoint &p, bool player_immune, const std::string &exp_name)
Triggers a flashbang explosion at p.
Definition: explosion.cpp:894
void emp_blast(const tripoint &p)
Triggers an EMP blast at p.
Definition: explosion.cpp:1013
bool consume_liquid(item &liquid, const int radius)
Consume / handle as much of the liquid as possible in varying ways.
void sound(const tripoint &p, int vol, sound_t category, const std::string &description, bool ambient=false, const std::string &id="", const std::string &variant="default")
Sound at (p) of intensity (vol)
Definition: sounds.cpp:177
bool teleport(Creature &critter, int min_distance=2, int max_distance=12, bool safe=false, bool add_teleglow=true)
Teleports a creature to a tile within min_distance and max_distance tiles.
Definition: teleport.cpp:24
constexpr value_type to_fahrenheit(const quantity< value_type, temperature_in_millidegree_celsius_tag > &v)
constexpr quantity< value_type, energy_in_joule_tag > from_kilojoule(const value_type v)
Definition: units_energy.h:32
overmapbuffer overmap_buffer
bool one_in(int chance)
Definition: rng.cpp:65
std::string string_format(std::string_view format, Args &&...args)
Simple wrapper over string_formatter::parse.
std::vector< enchantment_id > enchantments
bionic enchantments
Definition: bionics.h:109
itype_id fake_item
Fake item created for crafting with this bionic available.
Definition: bionics.h:101
units::energy power_activate
Power cost on activation.
Definition: bionics.h:37
int charge_time
How often a bionic draws or produces power while active in turns.
Definition: bionics.h:45
bool is_remote_fueled
This bionic draws power through a cable.
Definition: bionics.h:63
bool has_flag(const flag_str_id &flag) const
Definition: bionics.cpp:242
itype_id ammo_loaded
Definition: bionics.h:157
bool is_auto_start_keep_full() const
Definition: bionics.cpp:2750
bionic_id id
Definition: bionics.h:152
unsigned int ammo_count
Definition: bionics.h:159
bool powered
Definition: bionics.h:155
static damage_instance physical(float bash, float cut, float stab, float arpen=0.0f)
Definition: damage.cpp:27
std::string open_message
Definition: mapdata.h:165
void add_effect(const ammo_effect_str_id &id)
Definition: projectile.h:58
damage_instance impact
Definition: projectile.h:21
bool affects_player
Definition: explosion.h:30
units::temperature temperature
Definition: weather_gen.h:16
double humidity
Definition: weather_gen.h:17
double pressure
Definition: weather_gen.h:18
string_id< material_type > material_id
Definition: type_id.h:92
double convert_velocity(int velocity, const units_type vel_units)
Convert internal velocity units to units defined by user.
const char * velocity_units(const units_type vel_units)
Create a units label for a velocity value.
@ VU_WIND
Definition: units_utility.h:15

References _, item::active, sounds::activity, projectile::add_effect(), Creature::add_effect(), map::add_field(), map::add_item_or_charges(), Creature::add_msg_if_player(), shockwave_data::affects_player, bionic::ammo_count, bionic::ammo_loaded, item::ammo_set(), apply_damage(), Creature::as_avatar(), map::bash(), item_stack::begin(), bio_adrenaline, bio_blood_anal, bio_blood_filter, bio_cqb, bio_earplugs, bio_ears, bio_emp, bio_evap, bio_flashbang, bio_geiger, bio_hydraulics, bio_jointservo, bio_lighter, bio_lockpick, bio_magnet, bio_meteorologist, bio_plutdump, bio_probability_travel, bio_radscrubber, bio_remote, bio_resonator, bio_shockwave, bio_teleport, bio_time_freeze, bio_tools, bio_torsionratchet, bio_water_extractor, burn_fuel(), bionic_data::charge_time, bionic::charge_timer, item::charges, choose_adjacent(), colorize(), sounds::combat, conduct_blood_analysis(), liquid_handler::consume_liquid(), convert_velocity(), shockwave_data::dam_mult, dispose_item(), effect_adrenaline, effect_badpoison, effect_bloodworms, effect_cig, effect_cocaine_high, effect_datura, effect_dermatik, effect_drunk, effect_fungus, effect_hallu, effect_iodine, effect_meth, effect_pblue, effect_pkill1, effect_pkill2, effect_pkill3, effect_pkill_l, effect_poison, effect_stung, effect_teleglow, effect_took_flumed, effect_took_prozac, effect_took_prozac_bad, effect_took_xanax, effect_visuals, effect_weed_high, explosion_handler::emp_blast(), bionic_data::enchantments, item_stack::end(), dealt_projectile_attack::end_point, enough_power_for(), map_stack::erase(), f_null, bionic_data::fake_item, fd_fire, avatar_action::fire_ranged_bionic(), avatar_action::fire_wielded_weapon(), flag_BIONIC_GUN, flag_BIONIC_TOGGLED, flag_BIONIC_WEAPON, flag_CABLE_SPOOL(), flag_NO_UNWIELD(), flag_SEALED(), explosion_handler::flashbang(), shockwave_data::force, force_comedown(), units::from_kilojoule(), g, get_dirstring(), Creature::get_effect(), get_local_humidity(), get_local_windchill(), get_local_windpower(), get_lockpicking_open_result(), get_map(), get_player_character(), get_power_level(), weather_manager::get_precise(), get_rad(), Creature::get_value(), get_weather(), global_omt_location(), has_active_bionic(), Creature::has_effect(), bionic_data::has_flag(), item::has_flag(), map::has_flag(), map::has_items(), w_point::humidity, map::i_at(), bionic::id, projectile::impact, bionic::incapacitated_time, bionic::info(), invalidate_crafting_inventory(), item::invlet, invoke_item(), bionic::is_auto_start_keep_full(), string_id< T >::is_empty(), map::is_flammable(), is_mounted(), item::is_null(), bionic_data::is_remote_fueled, visitable< Character >::items_with(), itype_water_clean, m_bad, m_good, m_info, m_mixed, m_neutral, martial_arts_data, Creature::mod_moves(), mod_power_level(), mod_rad(), my_bionics, bionic_data::name, lockpicking_open_result::new_furn_type, lockpicking_open_result::new_ter_type, one_in(), lockpicking_open_result::open_message, overmap_buffer, damage_instance::physical(), map::points_in_radius(), pos(), bionic_data::power_activate, bionic::powered, w_point::pressure, print_humidity(), print_pressure(), print_temperature(), projectile_attack(), query_yn(), shockwave_data::radius, projectile::range, reactor_plut, recalculate_enchantment_cache(), Creature::remove_effect(), reset(), reset_encumbrance(), rl_dist(), rng(), set_painkiller(), set_power_level(), set_rad(), set_stim(), explosion_handler::shockwave(), slow_rad, sounds::sound(), projectile::speed, calendar::start_of_cataclysm, string_format(), shockwave_data::stun, behavior::success, t_null, tank_plut, teleport::teleport(), w_point::temperature, overmapbuffer::ter(), item::tname(), units::to_fahrenheit(), units::to_kilojoule(), calendar::turn, map::veh_at(), velocity_units(), VU_WIND, weapon, and weight_capacity().

Referenced by npc::activate_bionic_by_id(), add_bionic(), show_bionics_ui(), and npc::use_bionic_by_id().

◆ activate_mutation()

void Character::activate_mutation ( const trait_id mutation)

Definition at line 470 of file mutation.cpp.

471{
472 const mutation_branch &mdata = mut.obj();
473 char_trait_data &tdata = my_mutations[mut];
474 // You can take yourself halfway to Near Death levels of hunger/thirst.
475 // Fatigue can go to Exhausted.
476 if( !can_use_mutation_warn( mut, *this ) ) {
477 return;
478 }
480 tdata.powered = true;
481
482 if( !mut->enchantments.empty() ) {
484 }
485
486 if( mdata.transform ) {
487 const cata::value_ptr<mut_transform> trans = mdata.transform;
488 mod_moves( - trans->moves );
489 switch_mutations( mut, trans->target, trans->active );
490 return;
491 }
492
493 if( mut == trait_WEB_WEAVER ) {
494 g->m.add_field( pos(), fd_web, 1 );
495 add_msg_if_player( _( "You start spinning web with your spinnerets!" ) );
496 } else if( mut == trait_BURROW ) {
497 tdata.powered = false;
498 item burrowing_item( itype_id( "fake_burrowing" ) );
499 invoke_item( &burrowing_item );
500 return; // handled when the activity finishes
501 } else if( mut == trait_SLIMESPAWNER ) {
502 monster *const slime = g->place_critter_around( mtype_id( "mon_player_blob" ), pos(), 1 );
503 if( !slime ) {
504 // Oops, no room to divide!
505 add_msg_if_player( m_bad, _( "You focus, but are too hemmed in to birth a new slimespring!" ) );
506 tdata.powered = false;
507 return;
508 }
510 _( "You focus, and with a pleasant splitting feeling, birth a new slimespring!" ) );
511 slime->friendly = -1;
512 if( one_in( 3 ) ) {
514 //~ Usual enthusiastic slimespring small voices! :D
515 _( "wow! you look just like me! we should look out for each other!" ) );
516 } else if( one_in( 2 ) ) {
517 //~ Usual enthusiastic slimespring small voices! :D
518 add_msg_if_player( m_good, _( "come on, big me, let's go!" ) );
519 } else {
520 //~ Usual enthusiastic slimespring small voices! :D
521 add_msg_if_player( m_good, _( "we're a team, we've got this!" ) );
522 }
523 tdata.powered = false;
524 return;
525 } else if( mut == trait_NAUSEA || mut == trait_VOMITOUS ) {
526 vomit();
527 tdata.powered = false;
528 return;
529 } else if( mut == trait_M_FERTILE ) {
530 spores();
531 tdata.powered = false;
532 return;
533 } else if( mut == trait_M_BLOOM ) {
534 blossoms();
535 tdata.powered = false;
536 return;
537 } else if( mut == trait_M_PROVENANCE ) {
538 spores(); // double trouble!
539 blossoms();
540 tdata.powered = false;
541 return;
542 } else if( mut == trait_SELFAWARE ) {
543 print_health();
544 tdata.powered = false;
545 return;
546 } else if( mut == trait_TREE_COMMUNION ) {
547 tdata.powered = false;
548 if( !overmap_buffer.ter( global_omt_location() ).obj().is_wooded() ) {
549 add_msg_if_player( m_info, _( "You can only do that in a wooded area." ) );
550 return;
551 }
552 // Check for adjacent trees.
553 bool adjacent_tree = false;
554 for( const tripoint &p2 : g->m.points_in_radius( pos(), 1 ) ) {
555 if( g->m.has_flag( "TREE", p2 ) ) {
556 adjacent_tree = true;
557 }
558 }
559 if( !adjacent_tree ) {
560 add_msg_if_player( m_info, _( "You can only do that next to a tree." ) );
561 return;
562 }
563
565 add_msg_if_player( _( "You reach out to the trees with your roots." ) );
566 } else {
568 _( "You lay next to the trees letting your hair roots tangle with the trees." ) );
569 }
570
572
574 const time_duration startup_time = has_trait( trait_ROOTS3 ) ? rng( 15_minutes,
575 30_minutes ) : rng( 60_minutes, 90_minutes );
576 activity.values.push_back( to_turns<int>( startup_time ) );
577 return;
578 } else {
579 const time_duration startup_time = rng( 120_minutes, 180_minutes );
580 activity.values.push_back( to_turns<int>( startup_time ) );
581 return;
582 }
583 } else if( mut == trait_DEBUG_BIONIC_POWER ) {
584 mod_max_power_level( 100_kJ );
585 add_msg_if_player( m_good, _( "Bionic power storage increased by 100." ) );
586 tdata.powered = false;
587 return;
588 } else if( mut == trait_DEBUG_BIONIC_POWERGEN ) {
589 int npower;
590 if( query_int( npower, "Modify bionic power by how much? (Values are in joules)" ) ) {
592 add_msg_if_player( m_good, "Bionic power increased by %dJ.", npower );
593 tdata.powered = false;
594 }
595 return;
596 } else if( !mdata.spawn_item.is_empty() ) {
597 item tmpitem( mdata.spawn_item );
598 i_add_or_drop( tmpitem );
600 tdata.powered = false;
601 return;
602 } else if( !mdata.ranged_mutation.is_empty() ) {
605 tdata.powered = false;
606 return;
607 }
608}
mutation_collection my_mutations
Traits / mutations of the character.
Definition: character.h:2123
player_activity activity
Definition: character.h:1541
void mod_max_power_level(const units::energy &npower_max)
Definition: character.cpp:1917
void vomit()
Handles Character vomiting effects.
Definition: character.cpp:7654
void print_health() const
Definition: character.cpp:4183
void blossoms()
Definition: character.cpp:8746
void switch_mutations(const trait_id &switched, const trait_id &target, bool start_powered)
Unset switched mutation and set target mutation instead.
Definition: mutation.cpp:184
void spores()
Definition: character.cpp:8732
bool i_add_or_drop(item &it, int qty=1)
Sets invlet and adds to inventory if possible, drops otherwise, returns true if either succeeded.
Definition: character.cpp:2377
void mutation_spend_resources(const trait_id &mut)
Removes the appropriate costs (NOTE: will reapply mods & recalc sightlines in case of newly activated...
Definition: mutation.cpp:1713
void assign_activity(const activity_id &type, int moves=calendar::INDEFINITELY_LONG, int index=-1, int pos=INT_MIN, const std::string &name="")
Legacy activity assignment, does not work for any activites using the new activity_actor class and ma...
Definition: character.cpp:9145
This class is essentially a copyable unique pointer.
Definition: value_ptr.h:19
int friendly
Definition: monster.h:470
std::vector< int > values
A duration defined as a number of specific time units.
Definition: calendar.h:180
field_type_id fd_web
Definition: field_type.cpp:340
static const activity_id ACT_TREE_COMMUNION("ACT_TREE_COMMUNION")
static const trait_id trait_M_FERTILE("M_FERTILE")
static const trait_id trait_BURROW("BURROW")
static const trait_id trait_SLIMESPAWNER("SLIMESPAWNER")
static const trait_id trait_ROOTS2("ROOTS2")
static const trait_id trait_WEB_WEAVER("WEB_WEAVER")
bool can_use_mutation_warn(const trait_id &mut, const Character &character)
Calls can_use_mutation and if it fails, print a standard message.
Definition: mutation.cpp:1702
static const trait_id trait_M_BLOOM("M_BLOOM")
static const trait_id trait_VOMITOUS("VOMITOUS")
static const trait_id trait_SELFAWARE("SELFAWARE")
static const trait_id trait_DEBUG_BIONIC_POWERGEN("DEBUG_BIONIC_POWERGEN")
static const trait_id trait_NAUSEA("NAUSEA")
static const trait_id trait_M_PROVENANCE("M_PROVENANCE")
static const trait_id trait_TREE_COMMUNION("TREE_COMMUNION")
static const trait_id trait_DEBUG_BIONIC_POWER("DEBUG_BIONIC_POWER")
static const trait_id trait_ROOTS3("ROOTS3")
void fire_ranged_mutation(avatar &you, const item &fake_gun)
Stores fake gun specified by the mutation and starts interactive aiming.
constexpr quantity< value_type, energy_in_joule_tag > from_joule(const value_type v)
Definition: units_energy.h:25
bool query_int(int &result, int default_val, const std::string &text)
Definition: output.cpp:718
bool powered
Whether the mutation is activated.
Definition: character.h:202
std::string ranged_mutation_message() const
std::string spawn_item_message() const
cata::value_ptr< mut_transform > transform
Definition: mutation.h:153
itype_id spawn_item
The item, if any, spawned by the mutation.
Definition: mutation.h:205
itype_id ranged_mutation
The fake gun, if any, spawned and fired by the ranged mutation.
Definition: mutation.h:243

References _, ACT_TREE_COMMUNION, activity, Creature::add_msg_if_player(), assign_activity(), blossoms(), can_use_mutation_warn(), mutation_branch::enchantments, fd_web, avatar_action::fire_ranged_mutation(), monster::friendly, units::from_joule(), g, global_omt_location(), has_trait(), i_add_or_drop(), invoke_item(), string_id< T >::is_empty(), itype_id, m_bad, m_good, m_info, mod_max_power_level(), Creature::mod_moves(), mod_power_level(), mtype_id, mutation_spend_resources(), my_mutations, string_id< T >::obj(), one_in(), overmap_buffer, pos(), char_trait_data::powered, print_health(), query_int(), mutation_branch::ranged_mutation, mutation_branch::ranged_mutation_message(), recalculate_enchantment_cache(), rng(), mutation_branch::spawn_item, mutation_branch::spawn_item_message(), spores(), switch_mutations(), overmapbuffer::ter(), trait_BURROW, trait_DEBUG_BIONIC_POWER, trait_DEBUG_BIONIC_POWERGEN, trait_M_BLOOM, trait_M_FERTILE, trait_M_PROVENANCE, trait_NAUSEA, trait_ROOTS2, trait_ROOTS3, trait_SELFAWARE, trait_SLIMESPAWNER, trait_TREE_COMMUNION, trait_VOMITOUS, trait_WEB_WEAVER, mutation_branch::transform, player_activity::values, and vomit().

Referenced by show_mutations_ui(), and detail::show_mutations_ui_internal().

◆ active_light()

float Character::active_light ( ) const

Returns character luminosity based on the brightest active item they are carrying.

Definition at line 6272 of file character.cpp.

6273{
6274 float lumination = 0;
6275
6276 int maxlum = 0;
6277 has_item_with( [&maxlum]( const item & it ) {
6278 const int lumit = it.getlight_emit();
6279 if( maxlum < lumit ) {
6280 maxlum = lumit;
6281 }
6282 return false; // continue search, otherwise has_item_with would cancel the search
6283 } );
6284
6285 lumination = static_cast<float>( maxlum );
6286
6287 float mut_lum = 0.0f;
6288 for( const std::pair<const trait_id, char_trait_data> &mut : my_mutations ) {
6289 if( mut.second.powered ) {
6290 float curr_lum = 0.0f;
6291 for( const auto elem : mut.first->lumination ) {
6292 int coverage = 0;
6293 for( const item &i : worn ) {
6294 if( i.covers( elem.first ) && !i.has_flag( flag_ALLOWS_NATURAL_ATTACKS ) &&
6295 !i.has_flag( flag_SEMITANGIBLE ) &&
6296 !i.has_flag( flag_PERSONAL ) && !i.has_flag( flag_AURA ) ) {
6297 coverage += i.get_coverage();
6298 }
6299 }
6300 curr_lum += elem.second * ( 1 - ( coverage / 100.0f ) );
6301 }
6302 mut_lum += curr_lum;
6303 }
6304 }
6305
6306 lumination = std::max( lumination, mut_lum );
6307
6308 if( lumination < 60 && has_active_bionic( bio_flashlight ) ) {
6309 lumination = 60;
6310 } else if( lumination < 25 && has_artifact_with( AEP_GLOW ) ) {
6311 lumination = 25;
6312 } else if( lumination < 5 && ( has_effect( effect_glowing ) ||
6314 has_effect( effect_glowy_led ) ) ) ) {
6315 lumination = 5;
6316 }
6317 return lumination;
6318}
static const efftype_id effect_glowy_led("glowy_led")
static const bionic_id bio_flashlight("bio_flashlight")
static const std::string flag_SEMITANGIBLE("SEMITANGIBLE")
static const std::string flag_ALLOWS_NATURAL_ATTACKS("ALLOWS_NATURAL_ATTACKS")
static const efftype_id effect_glowing("glowing")
static const std::string flag_AURA("AURA")
static const bionic_id bio_tattoo_led("bio_tattoo_led")
static const std::string flag_PERSONAL("PERSONAL")
virtual bool has_artifact_with(art_effect_passive effect) const
Definition: character.cpp:3181
int getlight_emit() const
How much light (see lightmap.cpp) the item emits (it's assumed to be circular).
Definition: item.cpp:8385
bool has_item_with(const std::function< bool(const item &)> &filter) const
Returns true if any item (including those within a container) matches the filter.
Definition: visitable.cpp:104
@ AEP_GLOW
Definition: enums.h:115

References AEP_GLOW, bio_flashlight, bio_tattoo_led, effect_glowing, effect_glowy_led, flag_ALLOWS_NATURAL_ATTACKS(), flag_AURA(), flag_PERSONAL(), flag_SEMITANGIBLE(), item::getlight_emit(), has_active_bionic(), has_artifact_with(), Creature::has_effect(), visitable< Character >::has_item_with(), my_mutations, and worn.

Referenced by map::apply_character_light(), and character_funcs::fine_detail_vision_mod().

◆ add_addiction()

void Character::add_addiction ( add_type  type,
int  strength 
)

Adds an addiction to the player.

Definition at line 1894 of file suffer.cpp.

1895{
1896 if( type == add_type::NONE ) {
1897 return;
1898 }
1899 time_duration timer = 2_hours;
1900 if( has_trait( trait_ADDICTIVE ) ) {
1901 strength *= 2;
1902 timer = 1_hours;
1903 } else if( has_trait( trait_NONADDICTIVE ) ) {
1904 strength /= 2;
1905 timer = 6_hours;
1906 }
1907 //Update existing addiction
1908 for( auto &i : addictions ) {
1909 if( i.type != type ) {
1910 continue;
1911 }
1912
1913 if( i.sated < 0_turns ) {
1914 i.sated = timer;
1915 } else if( i.sated < 10_minutes ) {
1916 // TODO: Make this variable?
1917 i.sated += timer;
1918 } else {
1919 i.sated += timer / 2;
1920 }
1921 if( i.intensity < MAX_ADDICTION_LEVEL && strength > i.intensity * rng( 2, 5 ) ) {
1922 i.intensity++;
1923 }
1924
1925 add_msg( m_debug, "Updating addiction: %d intensity, %d sated",
1926 i.intensity, to_turns<int>( i.sated ) );
1927
1928 return;
1929 }
1930
1931 // Add a new addiction
1932 const int roll = rng( 0, 100 );
1933 add_msg( m_debug, "Addiction: roll %d vs strength %d", roll, strength );
1934 if( roll < strength ) {
1935 const std::string &type_name = addiction_type_name( type );
1936 add_msg( m_debug, "%s got addicted to %s", disp_name(), type_name );
1937 addictions.emplace_back( type, 1 );
1938 g->events().send<event_type::gains_addiction>( getID(), type );
1939 }
1940}
std::string addiction_type_name(add_type const cur)
Returns the name of an addiction.
Definition: addiction.cpp:253
constexpr int MAX_ADDICTION_LEVEL
Definition: addiction.h:14
std::string disp_name(bool possessive=false, bool capitalize_first=false) const override
Returns either "you" or the player's name.
Definition: character.cpp:566
std::vector< addiction > addictions
Definition: character.h:1571
character_id getID() const
Definition: character.cpp:483
@ m_debug
Definition: enums.h:271
@ type
Definition: enums.h:75
void add_msg(std::string msg)
Definition: messages.cpp:884
static const trait_id trait_NONADDICTIVE("NONADDICTIVE")
static const trait_id trait_ADDICTIVE("ADDICTIVE")

References add_msg(), addiction_type_name(), addictions, disp_name(), g, gains_addiction, getID(), has_trait(), m_debug, MAX_ADDICTION_LEVEL, NONE, rng(), trait_ADDICTIVE, trait_NONADDICTIVE, and type.

Referenced by iexamine::flower_poppy(), marloss_common(), and modify_addiction().

◆ add_bionic()

void Character::add_bionic ( const bionic_id b)

Adds a bionic to my_bionics[].

Definition at line 2519 of file bionics.cpp.

2520{
2521 if( has_bionic( b ) ) {
2522 debugmsg( "Tried to install bionic %s that is already installed!", b.c_str() );
2523 return;
2524 }
2525
2526 const units::energy pow_up = b->capacity;
2527 mod_max_power_level( pow_up );
2529 add_msg_if_player( m_good, _( "Increased storage capacity by %i." ),
2530 units::to_kilojoule( pow_up ) );
2531 // Power Storage CBMs are not real bionic units, so return without adding it to my_bionics
2532 return;
2533 }
2534
2535 my_bionics->push_back( bionic( b, get_free_invlet( *my_bionics ) ) );
2536 if( b == bio_tools || b == bio_ears ) {
2537 activate_bionic( my_bionics->back() );
2538 }
2539
2540 for( const bionic_id &inc_bid : b->included_bionics ) {
2541 add_bionic( inc_bid );
2542 }
2543
2544 for( const std::pair<const spell_id, int> &spell_pair : b->learned_spells ) {
2545 const spell_id learned_spell = spell_pair.first;
2546 if( learned_spell->spell_class != trait_id( "NONE" ) ) {
2547 const trait_id spell_class = learned_spell->spell_class;
2548 // spells you learn from a bionic overwrite the opposite spell class.
2549 // for best UX, include those spell classes in "canceled_mutations"
2550 if( !has_trait( spell_class ) ) {
2551 set_mutation( spell_class );
2552 on_mutation_gain( spell_class );
2553 add_msg_if_player( spell_class->desc() );
2554 }
2555 }
2556 if( !magic->knows_spell( learned_spell ) ) {
2557 magic->learn_spell( learned_spell, *this, true );
2558 }
2559 spell &known_spell = magic->get_spell( learned_spell );
2560 // spells you learn from installing a bionic upgrade spells you know if they are the same
2561 if( known_spell.get_level() < spell_pair.second ) {
2562 known_spell.set_level( spell_pair.second );
2563 }
2564 }
2565
2568 if( !b->enchantments.empty() ) {
2570 }
2571}
static const bionic_id bio_power_storage("bio_power_storage")
static const bionic_id bio_power_storage_mkII("bio_power_storage_mkII")
char get_free_invlet(bionic_collection &bionics)
Definition: bionics_ui.cpp:177
bool activate_bionic(bionic &bio, bool eff_only=false)
Handles bionic activation effects of the entered bionic, returns if anything activated.
Definition: bionics.cpp:532
void on_mutation_gain(const trait_id &mid)
Called when a mutation is gained.
Definition: character.cpp:9846
bool has_bionic(const bionic_id &b) const
Returns true if the player has the entered bionic id.
Definition: character.cpp:1795
void add_bionic(const bionic_id &b)
Adds a bionic to my_bionics[].
Definition: bionics.cpp:2519
void recalc_sight_limits()
Modifies the player's sight values Must be called when any of the following change: This must be call...
Definition: character.cpp:1610
void set_mutation(const trait_id &)
Add or removes a mutation on the player, but does not trigger mutation loss/gain effects.
Definition: mutation.cpp:154
pimpl< known_magic > magic
Definition: character.h:1448
trait_id spell_class
Definition: magic.h:236
Definition: magic.h:286
int get_level() const
Definition: magic.cpp:1034
void set_level(int nlevel)
Definition: magic.cpp:612
#define debugmsg(...)
Debug message of level DL::Error and class DC::DebugMsg, also includes the source file name and line,...
Definition: debug.h:74
constexpr double b
Definition: magic.cpp:1031
std::string desc() const

References _, activate_bionic(), add_bionic(), Creature::add_msg_if_player(), b, bio_ears, bio_power_storage, bio_power_storage_mkII, bio_tools, debugmsg, mutation_branch::desc(), get_free_invlet(), spell::get_level(), has_bionic(), has_trait(), m_good, magic, mod_max_power_level(), my_bionics, on_mutation_gain(), recalc_sight_limits(), recalculate_enchantment_cache(), reset_encumbrance(), spell::set_level(), set_mutation(), spell_type::spell_class, and units::to_kilojoule().

Referenced by add_bionic(), bionics_install_failure(), avatar::create(), deactivate_bionic(), player::load(), perform_install(), and npc::randomize().

◆ add_known_trap()

void Character::add_known_trap ( const tripoint pos,
const trap t 
)

Definition at line 10208 of file character.cpp.

10209{
10210 const tripoint p = get_map().getabs( pos );
10211 if( t.is_null() ) {
10212 known_traps.erase( p );
10213 } else {
10214 // TODO: known_traps should map to a trap_str_id
10215 known_traps[p] = t.id.str();
10216 }
10217}
trap_map known_traps
Definition: character.h:2114
tripoint getabs(const tripoint &p) const
Translates local (to this map) coordinates of a square to global absolute coordinates.
Definition: map.cpp:8277
const std::string & str() const
Returns the identifier as plain std::string.
Definition: string_id.h:255
bool is_null() const
Whether this is the null-traps, aka no trap at all.
Definition: trap.cpp:245
trap_str_id id
Definition: trap.h:87

References get_map(), map::getabs(), trap::id, trap::is_null(), known_traps, pos(), and string_id< T >::str().

Referenced by vehicle::handle_trap(), place_and_add_as_known(), and character_funcs::search_surroundings().

◆ add_miss_reason()

void Character::add_miss_reason ( const std::string &  reason,
unsigned int  weight 
)

Adds a reason for why the player would miss a melee attack.

To possibly be messaged to the player when he misses a melee attack.

Parameters
reasonA message for the player that gives a reason for him missing.
weightThe weight used when choosing what reason to pick when the player misses.

Definition at line 321 of file melee.cpp.

322{
323 melee_miss_reasons.add( reason, weight );
324
325}
struct weighted_int_list< std::string > melee_miss_reasons
Definition: character.h:2238

References melee_miss_reasons.

Referenced by temperature_effect::apply(), eff_fun_hallu(), get_miss_reason(), hardcoded_effects(), process_one_effect(), reset_stats(), and suffer_in_sunlight().

◆ add_morale()

void Character::add_morale ( const morale_type type,
int  bonus,
int  max_bonus = 0,
const time_duration duration = 1_hours,
const time_duration decay_start = 30_minutes,
bool  capped = false,
const itype item_type = nullptr 
)

Definition at line 9047 of file character.cpp.

9050{
9051 if( item_type != nullptr ) {
9052 morale->add( type, bonus, max_bonus, duration, decay_start, capped, *item_type );
9053 } else {
9054 morale->add( type, bonus, max_bonus, duration, decay_start, capped );
9055 }
9056}
pimpl< player_morale > morale
Definition: character.h:2176

References morale, and type.

Referenced by addict_effect(), apply_persistent_morale(), apply_wetness_morale(), iuse::artifact(), iuse::bell(), iuse::blech(), debug_menu::character_edit_menu(), iuse::datura(), monster::die(), avatar::do_read(), iuse::einktabletpc(), npc::finish_read(), ranged::fire_gun(), activity_handlers::generic_game_do_turn(), activity_handlers::haircut_finish(), hardcoded_effects(), marloss_add(), marloss_common(), activity_handlers::meditate_finish(), modify_morale(), spell_effect::morale(), iuse::mycus(), iuse::plantblech(), iuse::play_music(), activity_handlers::play_with_pet_finish(), iuse::portable_game(), game::process_artifact(), process_bionic(), firestarter_actor::resolve_firestarter_use(), set_up_butchery_activity(), activity_handlers::shaving_finish(), game::start_game(), suffer_from_chemimbalance(), suffer_from_other_mutations(), suffer_from_schizophrenia(), suffer_while_awake(), activity_handlers::tree_communion_do_turn(), update_bodytemp(), enzlave_actor::use(), musical_instrument_actor::use(), mutagen_actor::use(), mutagen_iv_actor::use(), activity_handlers::vibe_do_turn(), activity_handlers::vibe_finish(), and avatar::vomit().

◆ addiction_level()

int Character::addiction_level ( add_type  type) const

Returns the intensity of the specified addiction.

Definition at line 1963 of file suffer.cpp.

1964{
1965 auto iter = std::find_if( addictions.begin(), addictions.end(),
1966 [type]( const addiction & ad ) {
1967 return ad.type == type;
1968 } );
1969 return iter != addictions.end() ? iter->intensity : 0;
1970}

References addictions, and type.

Referenced by iuse::ecig(), mend(), process_one_effect(), and iuse::smoking().

◆ adjust_for_focus()

int Character::adjust_for_focus ( int  amount) const

Definition at line 9889 of file character.cpp.

9890{
9891 int effective_focus = focus_pool;
9892 if( has_trait( trait_FASTLEARNER ) ) {
9893 effective_focus += 15;
9894 }
9895 if( has_active_bionic( bio_memory ) ) {
9896 effective_focus += 10;
9897 }
9898 if( has_trait( trait_SLOWLEARNER ) ) {
9899 effective_focus -= 15;
9900 }
9901 effective_focus += ( get_int() - get_option<int>( "INT_BASED_LEARNING_BASE_VALUE" ) ) *
9902 get_option<int>( "INT_BASED_LEARNING_FOCUS_ADJUSTMENT" );
9903 double tmp = amount * ( effective_focus / 100.0 );
9904 return roll_remainder( tmp );
9905}
static const trait_id trait_FASTLEARNER("FASTLEARNER")
static const bionic_id bio_memory("bio_memory")
static const trait_id trait_SLOWLEARNER("SLOWLEARNER")
int focus_pool
Definition: character.h:1560
virtual int get_int() const
Definition: character.cpp:4064

References bio_memory, focus_pool, get_int(), has_active_bionic(), has_trait(), roll_remainder(), trait_FASTLEARNER, and trait_SLOWLEARNER.

Referenced by spell::casting_exp(), avatar::do_read(), and practice().

◆ age()

int Character::age ( ) const

Definition at line 6755 of file character.cpp.

6756{
6757 int years_since_cataclysm = to_turns<int>( calendar::turn - calendar::turn_zero ) /
6758 to_turns<int>( calendar::year_length() );
6759 return init_age + years_since_cataclysm;
6760}
int init_age
age in years at character creation
Definition: character.h:2108
time_duration year_length()
Definition: calendar.cpp:461
const time_point turn_zero
Represents time point 0.
Definition: calendar.cpp:26

References init_age, calendar::turn, calendar::turn_zero, and calendar::year_length().

Referenced by age_string(), and set_base_age().

◆ age_string()

std::string Character::age_string ( ) const

Definition at line 6762 of file character.cpp.

6763{
6764 //~ how old the character is in years. try to limit number of characters to fit on the screen
6765 std::string unformatted = _( "%d years" );
6766 return string_format( unformatted, age() );
6767}
int age() const
Definition: character.cpp:6755

References _, age(), and string_format().

Referenced by draw_stats_info(), and draw_stats_tab().

◆ all_items_with_flag()

std::vector< const item * > Character::all_items_with_flag ( const std::string &  flag) const

All items that have the given flag (item::has_flag).

Definition at line 9547 of file character.cpp.

9548{
9549 return items_with( [&flag]( const item & it ) {
9550 return it.has_flag( flag );
9551 } );
9552}

References item::has_flag(), and visitable< Character >::items_with().

Referenced by iexamine::choose_fertilizer(), iexamine::dimensional_portal(), has_fire(), and use_fire().

◆ allergy_type()

morale_type Character::allergy_type ( const item food) const

Returns allergy type or MORALE_NULL if not allergic for this character.

Definition at line 619 of file consumption.cpp.

620{
621 using allergy_tuple = std::tuple<trait_id, std::string, morale_type>;
622 static const std::array<allergy_tuple, 8> allergy_tuples = {{
629 }
630 };
631
632 for( const auto &tp : allergy_tuples ) {
633 if( has_trait( std::get<0>( tp ) ) &&
634 food.has_flag( std::get<1>( tp ) ) ) {
635 return std::get<2>( tp );
636 }
637 }
638
639 return MORALE_NULL;
640}
static const std::string flag_ALLERGEN_MILK("ALLERGEN_MILK")
static const std::string flag_ALLERGEN_VEGGY("ALLERGEN_VEGGY")
static const std::string flag_ALLERGEN_JUNK("ALLERGEN_JUNK")
static const std::string flag_ALLERGEN_FRUIT("ALLERGEN_FRUIT")
static const trait_id trait_ANTIWHEAT("ANTIWHEAT")
static const trait_id trait_ANTIJUNK("ANTIJUNK")
static const trait_id trait_VEGETARIAN("VEGETARIAN")
static const trait_id trait_LACTOSE("LACTOSE")
static const std::string flag_ALLERGEN_WHEAT("ALLERGEN_WHEAT")
static const std::string flag_ALLERGEN_MEAT("ALLERGEN_MEAT")
static const trait_id trait_MEATARIAN("MEATARIAN")
static const trait_id trait_ANTIFRUIT("ANTIFRUIT")
const morale_type MORALE_MEATARIAN("morale_meatarian")
const morale_type MORALE_ANTIJUNK("morale_antijunk")
const morale_type MORALE_ANTIWHEAT("morale_antiwheat")
const morale_type MORALE_ANTIFRUIT("morale_antifruit")
const morale_type MORALE_LACTOSE("morale_lactose")
const morale_type MORALE_VEGETARIAN("morale_vegetarian")
const morale_type MORALE_NULL("morale_null")

References flag_ALLERGEN_FRUIT(), flag_ALLERGEN_JUNK(), flag_ALLERGEN_MEAT(), flag_ALLERGEN_MILK(), flag_ALLERGEN_VEGGY(), flag_ALLERGEN_WHEAT(), item::has_flag(), has_trait(), MORALE_ANTIFRUIT, MORALE_ANTIJUNK, MORALE_ANTIWHEAT, MORALE_LACTOSE, MORALE_MEATARIAN, MORALE_NULL, MORALE_VEGETARIAN, trait_ANTIFRUIT, trait_ANTIJUNK, trait_ANTIWHEAT, trait_LACTOSE, trait_MEATARIAN, and trait_VEGETARIAN.

Referenced by item::color_in_inventory(), item::food_info(), modify_morale(), and will_eat().

◆ allocated_invlets()

invlets_bitset Character::allocated_invlets ( ) const

Only use for UI things.

Returns all invlets that are currently used in the player inventory, the weapon slot and the worn items.

Definition at line 2465 of file character.cpp.

2466{
2468
2469 invlets.set( weapon.invlet );
2470 for( const auto &w : worn ) {
2471 invlets.set( w.invlet );
2472 }
2473
2474 invlets[0] = false;
2475
2476 return invlets;
2477}
inventory inv
Definition: character.h:1544
invlets_bitset allocated_invlets() const
Definition: inventory.cpp:1261
std::bitset< std::numeric_limits< char >::max()> invlets_bitset
Definition: inventory.h:36

References inventory::allocated_invlets(), inv, item::invlet, weapon, and worn.

Referenced by inventory::assign_empty_invlet(), game_menus::inv::common(), and i_add().

◆ amount_of_storage_bionics()

std::pair< int, int > Character::amount_of_storage_bionics ( ) const

Returns amount of Storage CBMs in the corpse.

Definition at line 2615 of file bionics.cpp.

2616{
2618
2619 // exclude amount of power capacity obtained via non-power-storage CBMs
2620 for( const bionic &it : *my_bionics ) {
2621 lvl -= it.info().capacity;
2622 }
2623
2624 std::pair<int, int> results( 0, 0 );
2625 if( lvl <= 0_kJ ) {
2626 return results;
2627 }
2628
2629 const units::energy pow_mkI = bio_power_storage->capacity;
2631
2632 while( lvl >= std::min( pow_mkI, pow_mkII ) ) {
2633 if( one_in( 2 ) ) {
2634 if( lvl >= pow_mkI ) {
2635 results.first++;
2636 lvl -= pow_mkI;
2637 }
2638 } else {
2639 if( lvl >= pow_mkII ) {
2640 results.second++;
2641 lvl -= pow_mkII;
2642 }
2643 }
2644 }
2645 return results;
2646}
units::energy get_max_power_level() const
Definition: character.cpp:1890
units::energy capacity
Power bank size.
Definition: bionics.h:47

References bio_power_storage, bio_power_storage_mkII, bionic_data::capacity, get_max_power_level(), my_bionics, and one_in().

Referenced by place_corpse().

◆ amount_worn()

int Character::amount_worn ( const itype_id id) const

Returns the amount of item ‘type’ that is currently worn.

Definition at line 2159 of file character.cpp.

2160{
2161 int amount = 0;
2162 for( auto &elem : worn ) {
2163 if( elem.typeId() == id ) {
2164 ++amount;
2165 }
2166 }
2167 return amount;
2168}

References worn.

Referenced by can_wear().

◆ apply_damage()

void Character::apply_damage ( Creature source,
bodypart_id  hurt,
int  dam,
bool  bypass_med = false 
)
overridevirtual

Actually hurt the player, hurts a body_part directly, no armor reduction.

Implements Creature.

Definition at line 8358 of file character.cpp.

8360{
8362 // don't do any more damage if we're already dead
8363 // Or if we're debugging and don't want to die
8364 return;
8365 }
8366
8367 if( hurt == bodypart_id( "num_bp" ) ) {
8368 debugmsg( "Wacky body part hurt!" );
8369 hurt = bodypart_id( "torso" );
8370 }
8371
8372 mod_pain( dam / 2 );
8373
8374 const bodypart_id &part_to_damage = hurt->main_part;
8375
8376 const int dam_to_bodypart = std::min( dam, get_part_hp_cur( part_to_damage ) );
8377
8378 mod_part_hp_cur( part_to_damage, - dam_to_bodypart );
8380
8381 if( !weapon.is_null() && !as_player()->can_wield( weapon ).success() &&
8382 can_unwield( weapon ).success() ) {
8383 add_msg_if_player( _( "You are no longer able to wield your %s and drop it!" ),
8384 weapon.display_name() );
8386 i_rem( &weapon );
8387 }
8388 if( has_effect( effect_mending, part_to_damage->token ) ) {
8389 effect &e = get_effect( effect_mending, part_to_damage->token );
8390 float remove_mend = dam / 20.0f;
8391 e.mod_duration( -e.get_max_duration() * remove_mend );
8392 }
8393
8394 if( dam > get_painkiller() ) {
8395 on_hurt( source );
8396 }
8397
8398 if( is_dead_state() ) {
8399 // if the player killed himself, add it to the kill count list
8400 if( !is_npc() && !killer && source == g->u.as_character() ) {
8402 get_name() );
8403 }
8404 set_killer( source );
8405 }
8406
8407 if( !bypass_med ) {
8408 // remove healing effects if damaged
8409 int remove_med = roll_remainder( dam / 5.0f );
8410 if( remove_med > 0 && has_effect( effect_bandaged, part_to_damage->token ) ) {
8411 remove_med -= reduce_healing_effect( effect_bandaged, remove_med, part_to_damage );
8412 }
8413 if( remove_med > 0 && has_effect( effect_disinfected, part_to_damage->token ) ) {
8414 reduce_healing_effect( effect_disinfected, remove_med, part_to_damage );
8415 }
8416 }
8417}
void put_into_vehicle_or_drop(Character &c, item_drop_reason, const std::list< item > &items)
static const trait_id trait_DEBUG_NODMG("DEBUG_NODMG")
static const efftype_id effect_bandaged("bandaged")
static const efftype_id effect_disinfected("disinfected")
static const efftype_id effect_mending("mending")
void mod_pain(int npain) override
Modifies a pain value by player traits before passing it to Creature::mod_pain()
Definition: character.cpp:750
int get_painkiller() const
Returns intensity of painkillers
Definition: character.cpp:9760
item i_rem(int pos)
Remove a specific item from player possession.
Definition: character.cpp:2342
int reduce_healing_effect(const efftype_id &eff_id, int remove_med, const bodypart_id &hurt)
Reduce healing effect intensity, return initial intensity of the effect.
Definition: character.cpp:8575
void on_hurt(Creature *source, bool disturb=true)
Handles effects that happen when the player is damaged and aware of the fact.
Definition: character.cpp:8648
ret_val< bool > can_wield(const item &it) const
Check whether character is capable of wielding given item.
Definition: character.cpp:3056
ret_val< bool > can_unwield(const item &it) const
Check whether character is capable of unwielding given item.
Definition: character.cpp:3095
bool is_dead_state() const override
Returns true if the character should be dead.
Definition: character.cpp:488
std::string get_name() const override
Definition: character.cpp:5960
void mod_part_hp_cur(const bodypart_id &id, int mod)
Definition: creature.cpp:1596
int get_part_hp_cur(const bodypart_id &id) const
Definition: creature.cpp:1566
virtual player * as_player()
Definition: creature.h:122
void set_killer(Creature *killer)
Definition: creature.cpp:1437
virtual bool is_npc() const
Definition: creature.h:98
Creature * killer
Definition: creature.h:804
Definition: effect.h:161
void mod_duration(const time_duration &dur, bool alert=false)
Mods the duration, capping at max_duration if it exists.
Definition: effect.cpp:821
time_duration get_max_duration() const
Returns the maximum duration of an effect.
Definition: effect.cpp:801
void send(const cata::event &) const
Definition: event_bus.cpp:58
std::string display_name(unsigned int quantity=1) const
Returns the item name and the charges or contained charges (if the item can have charges at all).
Definition: item.cpp:4809
@ character_takes_damage
@ character_kills_character
event_bus & get_event_bus()
Definition: game.cpp:12019

References _, Creature::add_msg_if_player(), Creature::as_player(), can_unwield(), can_wield(), character_kills_character, character_takes_damage, debugmsg, item::display_name(), effect_bandaged, effect_disinfected, effect_mending, g, Creature::get_effect(), get_event_bus(), effect::get_max_duration(), get_name(), get_painkiller(), Creature::get_part_hp_cur(), get_player_character(), getID(), Creature::has_effect(), has_trait(), i_rem(), is_dead_state(), Creature::is_npc(), item::is_null(), Creature::killer, effect::mod_duration(), mod_pain(), Creature::mod_part_hp_cur(), on_hurt(), put_into_vehicle_or_drop(), reduce_healing_effect(), roll_remainder(), event_bus::send(), Creature::set_killer(), trait_DEBUG_NODMG, tumbling, and weapon.

Referenced by activate_bionic(), iuse::blech(), cough(), debug_menu::debug(), do_damage_for_bionic_failure(), eff_fun_bleed(), eff_fun_fungus(), iuse::ehandcuffs(), game::find_or_make_stairs(), heal_actor::finish_using(), iexamine::flower_cactus(), iexamine::flower_poppy(), game::handle_action(), start_location::handle_heli_crash(), hardcoded_effects(), knock_back_to(), activity_handlers::operation_do_turn(), process_one_effect(), suffer_from_radiation(), suffer_from_sunburn(), suffer_water_damage(), and suffer_while_underwater().

◆ apply_mods()

void Character::apply_mods ( const trait_id mut,
bool  add_remove 
)
protected

Applies stat mods to character.

Definition at line 206 of file mutation.cpp.

207{
208 int sign = add_remove ? 1 : -1;
209 int str_change = get_mod( mut, "STR" );
210 str_max += sign * str_change;
211 per_max += sign * get_mod( mut, "PER" );
212 dex_max += sign * get_mod( mut, "DEX" );
213 int_max += sign * get_mod( mut, "INT" );
214
215 if( str_change != 0 ) {
216 recalc_hp();
217 }
218}
void recalc_hp()
Recalculates HP after a change to max strength.
Definition: character.cpp:1563
int get_mod(const trait_id &mut, const std::string &arg) const
Retrieves a stat mod of a mutation.
Definition: mutation.cpp:195

References dex_max, get_mod(), int_max, per_max, recalc_hp(), and str_max.

Referenced by deactivate_mutation(), mutation_effect(), mutation_loss_effect(), mutation_spend_resources(), and suffer_mutation_power().

◆ apply_persistent_morale()

void Character::apply_persistent_morale ( )

Ensures persistent morale effects are up-to-date.

Definition at line 8962 of file character.cpp.

8963{
8964 // Hoarders get a morale penalty if they're not carrying a full inventory.
8965 if( has_trait( trait_HOARDER ) ) {
8966 int pen = ( volume_capacity() - volume_carried() ) / 125_ml;
8967 if( pen > 70 ) {
8968 pen = 70;
8969 }
8970 if( pen <= 0 ) {
8971 pen = 0;
8972 }
8973 if( has_effect( effect_took_xanax ) ) {
8974 pen = pen / 7;
8975 } else if( has_effect( effect_took_prozac ) ) {
8976 pen = pen / 2;
8977 }
8978 if( pen > 0 ) {
8979 add_morale( MORALE_PERM_HOARDER, -pen, -pen, 1_minutes, 1_minutes, true );
8980 }
8981 }
8982 // Nomads get a morale penalty if they stay near the same overmap tiles too long.
8984 const tripoint_abs_omt ompos = global_omt_location();
8985 float total_time = 0;
8986 // Check how long we've stayed in any overmap tile within 5 of us.
8987 const int max_dist = 5;
8988 for( const tripoint_abs_omt &pos : points_in_radius( ompos, max_dist ) ) {
8989 const float dist = rl_dist( ompos, pos );
8990 if( dist > max_dist ) {
8991 continue;
8992 }
8993 const auto iter = overmap_time.find( pos.xy() );
8994 if( iter == overmap_time.end() ) {
8995 continue;
8996 }
8997 // Count time in own tile fully, tiles one away as 4/5, tiles two away as 3/5, etc.
8998 total_time += to_moves<float>( iter->second ) * ( max_dist - dist ) / max_dist;
8999 }
9000 // Characters with higher tiers of Nomad suffer worse morale penalties, faster.
9001 int max_unhappiness;
9002 float min_time, max_time;
9003 if( has_trait( trait_NOMAD ) ) {
9004 max_unhappiness = 20;
9005 min_time = to_moves<float>( 2_days );
9006 max_time = to_moves<float>( 4_days );
9007 } else if( has_trait( trait_NOMAD2 ) ) {
9008 max_unhappiness = 40;
9009 min_time = to_moves<float>( 1_days );
9010 max_time = to_moves<float>( 2_days );
9011 } else { // traid_NOMAD3
9012 max_unhappiness = 60;
9013 min_time = to_moves<float>( 12_hours );
9014 max_time = to_moves<float>( 1_days );
9015 }
9016 // The penalty starts at 1 at min_time and scales up to max_unhappiness at max_time.
9017 const float t = ( total_time - min_time ) / ( max_time - min_time );
9018 const int pen = std::ceil( lerp_clamped( 0, max_unhappiness, t ) );
9019 if( pen > 0 ) {
9020 add_morale( MORALE_PERM_NOMAD, -pen, -pen, 1_minutes, 1_minutes, true );
9021 }
9022 }
9023
9024 if( has_trait( trait_PROF_FOODP ) ) {
9025 // Loosing your face is distressing
9026 if( !( is_wearing( itype_id( "foodperson_mask" ) ) ||
9027 is_wearing( itype_id( "foodperson_mask_on" ) ) ) ) {
9028 add_morale( MORALE_PERM_NOFACE, -20, -20, 1_minutes, 1_minutes, true );
9029 } else if( is_wearing( itype_id( "foodperson_mask" ) ) ||
9030 is_wearing( itype_id( "foodperson_mask_on" ) ) ) {
9032 }
9033
9034 if( is_wearing( itype_id( "foodperson_mask_on" ) ) ) {
9035 add_morale( MORALE_PERM_FPMODE_ON, 10, 10, 1_minutes, 1_minutes, true );
9036 } else {
9038 }
9039 }
9040}
constexpr T lerp_clamped(const T &min, const T &max, float t)
Linear interpolation with t clamped to [0, 1].
Definition: cata_utility.h:162
static const efftype_id effect_took_prozac("took_prozac")
static const trait_id trait_PROF_FOODP("PROF_FOODP")
static const trait_id trait_HOARDER("HOARDER")
static const trait_id trait_NOMAD2("NOMAD2")
static const trait_id trait_NOMAD3("NOMAD3")
static const trait_id trait_NOMAD("NOMAD")
static const efftype_id effect_took_xanax("took_xanax")
units::volume volume_capacity() const
Definition: character.cpp:2639
std::unordered_map< point_abs_omt, time_duration > overmap_time
Amount of time the player has spent in each overmap tile.
Definition: character.h:2254
units::volume volume_carried() const
Definition: character.cpp:2512
void add_morale(const morale_type &type, int bonus, int max_bonus=0, const time_duration &duration=1_hours, const time_duration &decay_start=30_minutes, bool capped=false, const itype *item_type=nullptr)
Definition: character.cpp:9047
void rem_morale(const morale_type &type)
Definition: character.cpp:9068
bool is_wearing(const item &itm) const
Returns true if the player is wearing the item.
Definition: character.cpp:3201
tripoint_range< Tripoint > points_in_radius(const Tripoint &center, const int radius, const int radiusz=0)
Definition: map_iterator.h:125
const morale_type MORALE_PERM_FPMODE_ON("morale_perm_fpmode_on")
const morale_type MORALE_PERM_HOARDER("morale_perm_hoarder")
const morale_type MORALE_PERM_NOMAD("morale_perm_nomad")
const morale_type MORALE_PERM_NOFACE("morale_perm_noface")
constexpr point xy() const
Definition: point.h:220

References add_morale(), effect_took_prozac, effect_took_xanax, global_omt_location(), Creature::has_effect(), has_trait(), is_wearing(), itype_id, lerp_clamped(), MORALE_PERM_FPMODE_ON, MORALE_PERM_HOARDER, MORALE_PERM_NOFACE, MORALE_PERM_NOMAD, overmap_time, points_in_radius(), pos(), rem_morale(), rl_dist(), trait_HOARDER, trait_NOMAD, trait_NOMAD2, trait_NOMAD3, trait_PROF_FOODP, volume_capacity(), volume_carried(), and tripoint::xy().

Referenced by debug_menu::character_edit_menu(), check_and_recover_morale(), avatar::create(), and update_morale().

◆ apply_skill_boost()

void Character::apply_skill_boost ( )
private

Applies skill-based boosts to stats.

Definition at line 3533 of file character.cpp.

3534{
3535 for( const skill_boost &boost : skill_boost::get_all() ) {
3536 // For migration, reset previously applied bonus.
3537 // Remove after 0.E or so.
3538 const std::string bonus_name = boost.stat() + std::string( "_bonus" );
3539 std::string previous_bonus = get_value( bonus_name );
3540 if( !previous_bonus.empty() ) {
3541 if( boost.stat() == "str" ) {
3542 str_max -= atoi( previous_bonus.c_str() );
3543 } else if( boost.stat() == "dex" ) {
3544 dex_max -= atoi( previous_bonus.c_str() );
3545 } else if( boost.stat() == "int" ) {
3546 int_max -= atoi( previous_bonus.c_str() );
3547 } else if( boost.stat() == "per" ) {
3548 per_max -= atoi( previous_bonus.c_str() );
3549 }
3550 remove_value( bonus_name );
3551 }
3552 // End migration code
3553 int skill_total = 0;
3554 for( const std::string &skill_str : boost.skills() ) {
3555 skill_total += get_skill_level( skill_id( skill_str ) );
3556 }
3557 mod_stat( boost.stat(), boost.calc_bonus( skill_total ) );
3558 if( boost.stat() == "str" ) {
3559 recalc_hp();
3560 }
3561 }
3562}
void mod_stat(const std::string &stat, float modifier) override
Definition: character.cpp:532
int get_skill_level(const skill_id &ident) const
Definition: character.cpp:3317
void remove_value(const std::string &key)
Definition: creature.cpp:1342
static const std::vector< skill_boost > & get_all()
Definition: skill_boost.cpp:15

References dex_max, skill_boost::get_all(), get_skill_level(), Creature::get_value(), int_max, mod_stat(), per_max, recalc_hp(), Creature::remove_value(), skill_id, and str_max.

Referenced by reset_stats().

◆ apply_wetness_morale()

void Character::apply_wetness_morale ( int  temperature)

Recalculates morale penalty/bonus from wetness based on mutations, equipment and temperature.

Definition at line 1809 of file suffer.cpp.

1810{
1811 // First, a quick check if we have any wetness to calculate morale from
1812 // Faster than checking all worn items for friendliness
1813 if( !std::any_of( body_wetness.begin(), body_wetness.end(),
1814 []( const int w ) {
1815 return w != 0;
1816} ) ) {
1817 return;
1818 }
1819
1820 // Normalize temperature to [-1.0,1.0]
1821 temperature = std::max( 0, std::min( 100, temperature ) );
1822 const double global_temperature_mod = -1.0 + ( 2.0 * temperature / 100.0 );
1823
1824 int total_morale = 0;
1825 const auto wet_friendliness = exclusive_flag_coverage( "WATER_FRIENDLY" );
1826 for( const body_part bp : all_body_parts ) {
1827 // Sum of body wetness can go up to 103
1828 const int part_drench = body_wetness[bp];
1829 if( part_drench == 0 ) {
1830 continue;
1831 }
1832
1833 const auto &part_arr = mut_drench[bp];
1834 const int part_ignored = part_arr[WT_IGNORED];
1835 const int part_neutral = part_arr[WT_NEUTRAL];
1836 const int part_good = part_arr[WT_GOOD];
1837
1838 if( part_ignored >= part_drench ) {
1839 continue;
1840 }
1841
1842 int bp_morale = 0;
1843 const bool is_friendly = wet_friendliness.test( bp );
1844 const int effective_drench = part_drench - part_ignored;
1845 if( is_friendly ) {
1846 // Using entire bonus from mutations and then some "human" bonus
1847 bp_morale = std::min( part_good, effective_drench ) + effective_drench / 2;
1848 } else if( effective_drench < part_good ) {
1849 // Positive or 0
1850 // Won't go higher than part_good / 2
1851 // Wet slime/scale doesn't feel as good when covered by wet rags/fur/kevlar
1852 bp_morale = std::min( effective_drench, part_good - effective_drench );
1853 } else if( effective_drench > part_good + part_neutral ) {
1854 // This one will be negative
1855 bp_morale = part_good + part_neutral - effective_drench;
1856 }
1857
1858 // Clamp to [COLD,HOT] and cast to double
1859 const double part_temperature =
1860 std::min( BODYTEMP_HOT, std::max( BODYTEMP_COLD, temp_cur[bp] ) );
1861 // 0.0 at COLD, 1.0 at HOT
1862 const double part_mod = ( part_temperature - BODYTEMP_COLD ) /
1864 // Average of global and part temperature modifiers, each in range [-1.0, 1.0]
1865 double scaled_temperature = ( global_temperature_mod + part_mod ) / 2;
1866
1867 if( bp_morale < 0 ) {
1868 // Damp, hot clothing on hot skin feels bad
1869 scaled_temperature = std::fabs( scaled_temperature );
1870 }
1871
1872 // For an unmutated human swimming in deep water, this will add up to:
1873 // +51 when hot in 100% water friendly clothing
1874 // -103 when cold/hot in 100% unfriendly clothing
1875 total_morale += static_cast<int>( bp_morale * ( 1.0 + scaled_temperature ) / 2.0 );
1876 }
1877
1878 if( total_morale == 0 ) {
1879 return;
1880 }
1881
1882 int morale_effect = total_morale / 8;
1883 if( morale_effect == 0 ) {
1884 if( total_morale > 0 ) {
1885 morale_effect = 1;
1886 } else {
1887 morale_effect = -1;
1888 }
1889 }
1890 // 61_seconds because decay is applied in 1_minutes increments
1891 add_morale( MORALE_WET, morale_effect, total_morale, 61_seconds, 61_seconds, true );
1892}
constexpr std::array< body_part, 12 > all_body_parts
Contains all valid body_part values in the order they are defined in.
Definition: bodypart.h:82
body_part
Definition: bodypart.h:39
body_part_set exclusive_flag_coverage(const std::string &flag) const
Bitset of all the body parts covered only with items with flag (or nothing)
Definition: character.cpp:4032
std::array< std::array< int, NUM_WATER_TOLERANCE >, num_bp > mut_drench
Definition: character.h:849
const morale_type MORALE_WET("morale_wet")
quantity< V, U > fabs(quantity< V, U > q)
Definition: units_def.h:136
quantity< int, temperature_in_millidegree_celsius_tag > temperature
static constexpr int BODYTEMP_COLD
Do not change this value, it is an arbitrary anchor on which other calculations are made.
Definition: weather.h:34
static constexpr int BODYTEMP_HOT
Level 2 hotness.
Definition: weather.h:38

References add_morale(), all_body_parts, body_wetness, BODYTEMP_COLD, BODYTEMP_HOT, exclusive_flag_coverage(), units::fabs(), MORALE_WET, mut_drench, temp_cur, WT_GOOD, WT_IGNORED, and WT_NEUTRAL.

Referenced by game::do_turn().

◆ armor_absorb()

bool Character::armor_absorb ( damage_unit du,
item armor 
)

Reduces and mutates du, prints messages about armor taking damage.

Returns
true if the armor was completely destroyed (and the item must be deleted).

Definition at line 8115 of file character.cpp.

8116{
8117 if( rng( 1, 100 ) > armor.get_coverage() ) {
8118 return false;
8119 }
8120
8121 // TODO: add some check for power armor
8122 armor.mitigate_damage( du );
8123
8124 // We want armor's own resistance to this type, not the resistance it grants
8125 const int armors_own_resist = armor.damage_resist( du.type, true );
8126 if( armors_own_resist > 1000 ) {
8127 // This is some weird type that doesn't damage armors
8128 return false;
8129 }
8130
8131 // Scale chance of article taking damage based on the number of parts it covers.
8132 // This represents large articles being able to take more punishment
8133 // before becoming ineffective or being destroyed.
8134 const int num_parts_covered = armor.get_covered_body_parts().count();
8135 if( !one_in( num_parts_covered ) ) {
8136 return false;
8137 }
8138
8139 // Don't damage armor as much when bypassed by armor piercing
8140 // Most armor piercing damage comes from bypassing armor, not forcing through
8141 const int raw_dmg = du.amount;
8142 if( raw_dmg > armors_own_resist ) {
8143 // If damage is above armor value, the chance to avoid armor damage is
8144 // 50% + 50% * 1/dmg
8145 if( one_in( raw_dmg ) || one_in( 2 ) ) {
8146 return false;
8147 }
8148 } else {
8149 // Sturdy items and power armors never take chip damage.
8150 // Other armors have 0.5% of getting damaged from hits below their armor value.
8151 if( armor.has_flag( flag_STURDY ) || !one_in( 200 ) ) {
8152 return false;
8153 }
8154 }
8155
8156 const material_type &material = armor.get_random_material();
8157 std::string damage_verb = ( du.type == DT_BASH ) ? material.bash_dmg_verb() :
8158 material.cut_dmg_verb();
8159
8160 const std::string pre_damage_name = armor.tname();
8161 const std::string pre_damage_adj = armor.get_base_material().dmg_adj( armor.damage_level( 4 ) );
8162
8163 // add "further" if the damage adjective and verb are the same
8164 std::string format_string = ( pre_damage_adj == damage_verb ) ?
8165 _( "Your %1$s is %2$s further!" ) : _( "Your %1$s is %2$s!" );
8166 add_msg_if_player( m_bad, format_string, pre_damage_name, damage_verb );
8167 //item is damaged
8168 if( is_player() ) {
8169 SCT.add( point( posx(), posy() ), direction::NORTH, remove_color_tags( pre_damage_name ), m_neutral,
8170 damage_verb,
8171 m_info );
8172 }
8173
8174 return armor.mod_damage( armor.has_flag( "FRAGILE" ) ?
8176}
static const std::string flag_STURDY("STURDY")
virtual bool is_player() const
Definition: creature.h:92
size_t count() const
Definition: bodypart.h:252
const material_type & get_random_material() const
Get a material reference to a random material that this item is made of.
Definition: item.cpp:7146
bool mod_damage(int qty, damage_type dt)
Apply damage to const itemrained by min_damage and max_damage.
Definition: item.cpp:6231
int damage_level(int max) const
Scale item damage to the given number of levels.
Definition: item.cpp:701
int damage_resist(damage_type dt, bool to_self=false) const
Resistance provided by this item against damage type given by an enum.
Definition: item.cpp:6376
const material_type & get_base_material() const
Get the basic (main) material of this item.
Definition: item.cpp:7151
body_part_set get_covered_body_parts() const
Bitset of all covered body parts.
Definition: item.cpp:753
int get_coverage() const
Returns the relative coverage that this item has when worn.
Definition: item.cpp:5905
void mitigate_damage(damage_unit &du) const
Assuming that specified du hit the armor, reduce du based on the item's resistance to the damage type...
Definition: item.cpp:6368
std::string cut_dmg_verb() const
Definition: material.cpp:190
std::string dmg_adj(int damage) const
Definition: material.cpp:195
std::string bash_dmg_verb() const
Definition: material.cpp:185
static constexpr int damage_scale
Definition: itype.h:1010

References _, scrollingcombattext::add(), Creature::add_msg_if_player(), damage_unit::amount, material_type::bash_dmg_verb(), body_part_set::count(), material_type::cut_dmg_verb(), item::damage_level(), item::damage_resist(), itype::damage_scale, material_type::dmg_adj(), DT_BASH, flag_STURDY(), item::get_base_material(), item::get_coverage(), item::get_covered_body_parts(), item::get_random_material(), item::has_flag(), Creature::is_player(), m_bad, m_info, m_neutral, item::mitigate_damage(), item::mod_damage(), NORTH, one_in(), posx(), posy(), remove_color_tags(), rng(), SCT, item::tname(), and damage_unit::type.

Referenced by absorb_hit().

◆ armwear_factor()

double Character::armwear_factor ( ) const

Same as footwear factor, but for arms.

Definition at line 8879 of file character.cpp.

8880{
8881 double ret = 0;
8882 if( wearing_something_on( bodypart_id( "arm_l" ) ) ) {
8883 ret += .5;
8884 }
8885 if( wearing_something_on( bodypart_id( "arm_r" ) ) ) {
8886 ret += .5;
8887 }
8888 return ret;
8889}
bool wearing_something_on(const bodypart_id &bp) const
Returns true if the character is wearing something on the entered body part.
Definition: character.cpp:8815

References cata::hash64_detail::ret, and wearing_something_on().

Referenced by suffer_in_sunlight().

◆ as_character() [1/2]

const Character * Character::as_character ( ) const
inlineoverridevirtual

Reimplemented from Creature.

Definition at line 227 of file character.h.

227 {
228 return this;
229 }

◆ as_character() [2/2]

Character * Character::as_character ( )
inlineoverridevirtual

Reimplemented from Creature.

Definition at line 224 of file character.h.

224 {
225 return this;
226 }

Referenced by doors::close_door(), and emit_radio_signal().

◆ assign_activity() [1/2]

void Character::assign_activity ( const activity_id type,
int  moves = calendar::INDEFINITELY_LONG,
int  index = -1,
int  pos = INT_MIN,
const std::string &  name = "" 
)

Legacy activity assignment, does not work for any activites using the new activity_actor class and may cause issues with resuming.

TODO: delete this once migration of activites to the activity_actor system is complete

Definition at line 9145 of file character.cpp.

9147{
9149}
int moves
Definition: creature.h:574

References assign_activity(), Creature::moves, name, pos(), and type.

Referenced by activate_mutation(), activity_on_turn_move_loot(), assign_activity(), iuse::burrow(), game::butcher(), butcher_corpse_activity(), butcher_submenu(), cast_spell(), iuse::chop_logs(), chop_plank_activity(), iuse::chop_tree(), chop_tree_activity(), iuse::clear_rubble(), complete_construction(), construction_activity(), iuse::craft(), iuse::cut_log_into_planks(), iuse::dig(), iuse::dig_channel(), crafting::disassemble_all(), overmap_ui::display(), talk_function::do_butcher(), talk_function::do_chop_plank(), talk_function::do_chop_trees(), talk_function::do_construction(), talk_function::do_farming(), talk_function::do_fishing(), talk_function::do_mining(), npc::do_pulp(), player_activity::do_turn(), talk_function::do_vehicle_deconstruct(), talk_function::do_vehicle_repair(), drop(), game::exam_vehicle(), iuse::fill_pit(), npc::find_job_to_perform(), talk_function::find_mount(), avatar_action::fire_ranged_bionic(), avatar_action::fire_ranged_mutation(), avatar_action::fire_wielded_weapon(), activity_handlers::fish_finish(), iuse::fishing_rod(), generic_multi_activity_check_requirement(), generic_multi_activity_do(), generic_multi_activity_handler(), talk_function::give_aid(), talk_function::give_all_aid(), avatar_funcs::gunmod_add(), iuse::hacksaw(), iuse::hairkit(), iuse::hammer(), iuse::hand_crank(), install_bionics(), vehicle::interact_with(), iuse::jackhammer(), loot(), iuse::makemound(), iuse::meditate(), monexamine::milk_source(), iuse::mind_splicer(), mine_activity(), iuse::oxytorch(), iuse::pickaxe(), game::place_player(), iexamine::plant_seed(), iuse::play_game(), monexamine::play_with(), avatar_action::plthrow(), iuse::portable_game(), prompt_disassemble_single(), avatar::read(), avatar_action::reload(), activity_handlers::resume_for_multi_activities(), iuse::robotcontrol(), iexamine::rubble(), iexamine::safe(), iuse::shavekit(), monexamine::shear_animal(), show_armor_layers_ui(), iexamine::shrub_wildveggies(), smash(), talk_function::sort_loot(), player::start_craft(), start_destination_activity(), game::start_hauling(), npc::start_read(), gates::toggle_gate(), avatar_funcs::toolmod_add(), iexamine::trap(), try_start_hacking(), avatar_funcs::try_to_sleep(), uninstall_bionic(), pick_lock_actor::use(), firestarter_actor::use(), enzlave_actor::use(), ammobelt_actor::use(), repair_item_actor::use(), heal_actor::use(), learn_spell_actor::use(), cast_spell_actor::use(), vehicle_activity(), iuse::vibe(), wait(), and wash_items().

◆ assign_activity() [2/2]

void Character::assign_activity ( const player_activity act,
bool  allow_resume = true 
)

Assigns activity to player, possibly resuming old activity if it's similar enough.

Definition at line 9151 of file character.cpp.

9152{
9153 bool resuming = false;
9154 if( allow_resume && !backlog.empty() && backlog.front().can_resume_with( act, *this ) ) {
9155 resuming = true;
9156 add_msg_if_player( _( "You resume your task." ) );
9157 activity = backlog.front();
9158 backlog.pop_front();
9159 } else {
9160 if( activity ) {
9161 backlog.push_front( activity );
9162 }
9163
9164 activity = act;
9165 }
9166
9167 activity.start_or_resume( *this, resuming );
9168
9169 if( is_npc() ) {
9171 npc *guy = dynamic_cast<npc *>( this );
9175 }
9176}
void cancel_stashed_activity()
Definition: character.cpp:888
std::list< player_activity > backlog
Definition: character.h:1542
Definition: npc.h:781
void set_attitude(npc_attitude new_attitude)
Definition: npc.cpp:3169
activity_id current_activity_id
Definition: npc.h:1245
void set_mission(npc_mission new_mission)
Definition: npc.cpp:3148
const activity_id & id() const
void start_or_resume(Character &who, bool resuming)
Preform necessary initialization to start or resume the activity.
@ NPCATT_ACTIVITY
Definition: npc.h:98
@ NPC_MISSION_ACTIVITY
Definition: npc.h:190
activity_id act
Definition: sounds.cpp:75

References _, act, activity, Creature::add_msg_if_player(), backlog, cancel_stashed_activity(), npc::current_activity_id, player_activity::id(), Creature::is_npc(), NPC_MISSION_ACTIVITY, NPCATT_ACTIVITY, npc::set_attitude(), npc::set_mission(), and player_activity::start_or_resume().

◆ assign_stashed_activity()

void Character::assign_stashed_activity ( )

Definition at line 910 of file character.cpp.

911{
915}
player_activity stashed_outbounds_backlog
Definition: character.h:1540
player_activity stashed_outbounds_activity
Definition: character.h:1539

References activity, backlog, cancel_stashed_activity(), stashed_outbounds_activity, and stashed_outbounds_backlog.

Referenced by npc::move().

◆ attack_cost()

int Character::attack_cost ( const item weap) const

Returns cost (in moves) of attacking with given item (no modifiers, like stuck)

Melee increases melee attack speed Dexterity increases attack speed

Definition at line 2220 of file melee.cpp.

2221{
2222 const int base_move_cost = weap.attack_cost() / 2;
2223 const int melee_skill = has_active_bionic( bionic_id( bio_cqb ) ) ? BIO_CQB_LEVEL : get_skill_level(
2224 skill_melee );
2225 /** @EFFECT_MELEE increases melee attack speed */
2226 const int skill_cost = static_cast<int>( ( base_move_cost * ( 15 - melee_skill ) / 15 ) );
2227 /** @EFFECT_DEX increases attack speed */
2228 const int dexbonus = dex_cur / 2;
2229 const int encumbrance_penalty = encumb( bp_torso ) +
2230 ( encumb( bp_hand_l ) + encumb( bp_hand_r ) ) / 2;
2231 const int ma_move_cost = mabuff_attack_cost_penalty();
2232 const float stamina_ratio = static_cast<float>( get_stamina() ) / static_cast<float>
2233 ( get_stamina_max() );
2234 // Increase cost multiplier linearly from 1.0 to 2.0 as stamina goes from 25% to 0%.
2235 const float stamina_penalty = 1.0 + std::max( ( 0.25f - stamina_ratio ) * 4.0f, 0.0f );
2236 const float ma_mult = mabuff_attack_cost_mult();
2237
2238 int move_cost = base_move_cost;
2239 // Stamina penalty only affects base/2 and encumbrance parts of the cost
2240 move_cost += encumbrance_penalty;
2241 move_cost *= stamina_penalty;
2242 move_cost += skill_cost;
2243 move_cost -= dexbonus;
2244
2246
2247 // Martial arts last. Flat has to be after mult, because comments say so.
2248 move_cost *= ma_mult;
2249 move_cost += ma_move_cost;
2250
2251 move_cost *= mutation_value( "attackcost_modifier" );
2252
2253 if( move_cost < 25 ) {
2254 return 25;
2255 }
2256
2257 return move_cost;
2258}
static int move_cost(const item &it, const tripoint &src, const tripoint &dest)
int get_stamina() const
Definition: character.cpp:7048
float mabuff_attack_cost_mult() const
Returns the multiplier on move cost of attacks.
float mutation_value(const std::string &val) const
Goes over all mutations, gets min and max of a value with given name.
Definition: character.cpp:6605
int mabuff_attack_cost_penalty() const
Returns the flat penalty to move cost of attacks.
int encumb(body_part bp) const
Returns ENC provided by armor, etc.
Definition: character.cpp:3989
double bonus_from_enchantments(double base, enchant_vals::mod value, bool round=false) const
Calculate bonus from enchantments for given base value.
Definition: character.cpp:7865
int get_stamina_max() const
Definition: character.cpp:7053
int attack_cost() const
Base number of moves (Creature::moves) that a single melee attack with this items takes.
Definition: item.cpp:5186
static constexpr int BIO_CQB_LEVEL
static const bionic_id bio_cqb("bio_cqb")
static const skill_id skill_melee("melee")

References item::attack_cost(), enchant_vals::ATTACK_COST, bio_cqb, BIO_CQB_LEVEL, bionic_id, bonus_from_enchantments(), bp_hand_l, bp_hand_r, bp_torso, dex_cur, encumb(), get_skill_level(), get_stamina(), get_stamina_max(), has_active_bionic(), mabuff_attack_cost_mult(), mabuff_attack_cost_penalty(), move_cost(), mutation_value(), and skill_melee.

Referenced by item::combat_info(), item::effective_dps(), melee_attack(), reach_attack(), and avatar_funcs::try_disarm_npc().

◆ attitude_to()

Creature::Attitude Character::attitude_to ( const Creature other) const
overridevirtual

Attitude (of this creature) towards another creature.

This might not be symmetric.

Implements Creature.

Reimplemented in npc.

Definition at line 10343 of file character.cpp.

10344{
10345 const auto m = dynamic_cast<const monster *>( &other );
10346 if( m != nullptr ) {
10347 if( m->friendly != 0 ) {
10348 return A_FRIENDLY;
10349 }
10350 switch( m->attitude( const_cast<Character *>( this ) ) ) {
10351 // player probably does not want to harm them, but doesn't care much at all.
10352 case MATT_FOLLOW:
10353 case MATT_FPASSIVE:
10354 case MATT_IGNORE:
10355 case MATT_FLEE:
10356 return A_NEUTRAL;
10357 // player does not want to harm those.
10358 case MATT_FRIEND:
10359 case MATT_ZLAVE:
10360 // Don't want to harm your zlave!
10361 return A_FRIENDLY;
10362 case MATT_ATTACK:
10363 return A_HOSTILE;
10364 case MATT_NULL:
10366 break;
10367 }
10368
10369 return A_NEUTRAL;
10370 }
10371
10372 const auto p = dynamic_cast<const npc *>( &other );
10373 if( p != nullptr ) {
10374 if( p->is_enemy() ) {
10375 return A_HOSTILE;
10376 } else if( p->is_player_ally() ) {
10377 return A_FRIENDLY;
10378 } else {
10379 return A_NEUTRAL;
10380 }
10381 } else if( &other == this ) {
10382 return A_FRIENDLY;
10383 }
10384
10385 return A_NEUTRAL;
10386}
@ A_NEUTRAL
Definition: creature.h:168
@ A_HOSTILE
Definition: creature.h:167
@ A_FRIENDLY
Definition: creature.h:169
@ MATT_ZLAVE
Definition: monster.h:63
@ MATT_FLEE
Definition: monster.h:59
@ NUM_MONSTER_ATTITUDES
Definition: monster.h:64
@ MATT_FRIEND
Definition: monster.h:57
@ MATT_FOLLOW
Definition: monster.h:61
@ MATT_ATTACK
Definition: monster.h:62
@ MATT_NULL
Definition: monster.h:56
@ MATT_IGNORE
Definition: monster.h:60
@ MATT_FPASSIVE
Definition: monster.h:58

References Creature::A_FRIENDLY, Creature::A_HOSTILE, Creature::A_NEUTRAL, MATT_ATTACK, MATT_FLEE, MATT_FOLLOW, MATT_FPASSIVE, MATT_FRIEND, MATT_IGNORE, MATT_NULL, MATT_ZLAVE, NUM_MONSTER_ATTITUDES, and other.

Referenced by game::is_hostile_within(), and show_armor_layers_ui().

◆ avoid_trap()

bool Character::avoid_trap ( const tripoint pos,
const trap tr 
) const
overridevirtual

Called when character triggers a trap, returns true if they don't set it off.

Dexterity increases chance to avoid traps Dodge increases chance to avoid traps

Implements Creature.

Definition at line 10219 of file character.cpp.

10220{
10221 /** @EFFECT_DEX increases chance to avoid traps */
10222
10223 /** @EFFECT_DODGE increases chance to avoid traps */
10224 int myroll = dice( 3, dex_cur + get_skill_level( skill_dodge ) * 1.5 );
10225 int traproll;
10226 if( tr.can_see( pos, *this ) ) {
10227 traproll = dice( 3, tr.get_avoidance() );
10228 } else {
10229 traproll = dice( 6, tr.get_avoidance() );
10230 }
10231
10232 return myroll >= traproll;
10233}
static const skill_id skill_dodge("dodge")
int dice(int number, int sides)
Definition: rng.cpp:85
int get_avoidance() const
Whether triggering the trap can be avoid (if greater than 0) and if so, this is compared to dodge ski...
Definition: trap.h:144
bool can_see(const tripoint &pos, const Character &p) const
Can player/npc p see this kind of trap, either by their memory (they known there is the trap) or by t...
Definition: trap.cpp:223

References trap::can_see(), dex_cur, dice(), trap::get_avoidance(), get_skill_level(), pos(), and skill_dodge.

◆ base_age()

int Character::base_age ( ) const

Definition at line 6740 of file character.cpp.

6741{
6742 return init_age;
6743}

References init_age.

Referenced by debug_menu::character_edit_menu(), char_creation::draw_age(), and set_description().

◆ base_height()

int Character::base_height ( ) const

Definition at line 6769 of file character.cpp.

6770{
6771 return init_height;
6772}
int init_height
height at character creation
Definition: character.h:2110

References init_height.

Referenced by debug_menu::character_edit_menu(), char_creation::draw_height(), and set_description().

◆ basic_symbol_color()

nc_color Character::basic_symbol_color ( ) const
overridevirtual

Implements Creature.

Reimplemented in npc.

Definition at line 5974 of file character.cpp.

5975{
5976 if( has_effect( effect_onfire ) ) {
5977 return c_red;
5978 }
5979 if( has_effect( effect_stunned ) ) {
5980 return c_light_blue;
5981 }
5982 if( has_effect( effect_boomered ) ) {
5983 return c_pink;
5984 }
5985 if( has_active_mutation( trait_id( "SHELL2" ) ) ) {
5986 return c_magenta;
5987 }
5988 if( is_underwater() ) {
5989 return c_blue;
5990 }
5993 return c_dark_gray;
5994 }
5995 if( move_mode == CMM_RUN ) {
5996 return c_yellow;
5997 }
5998 if( move_mode == CMM_CROUCH ) {
5999 return c_light_gray;
6000 }
6001 return c_white;
6002}
static const trait_id trait_DEBUG_CLOAK("DEBUG_CLOAK")
static const efftype_id effect_boomered("boomered")
static const bionic_id bio_cloak("bio_cloak")
static const efftype_id effect_stunned("stunned")
@ CMM_RUN
Definition: character.h:102
@ CMM_CROUCH
Definition: character.h:103
bool has_active_mutation(const trait_id &b) const
Definition: mutation.cpp:367
bool is_wearing_active_optcloak() const
Returns true if the player is wearing an active optical cloak.
Definition: character.cpp:3806
virtual bool is_underwater() const
Definition: creature.cpp:170
#define c_white
Definition: color.h:18
#define c_light_gray
Definition: color.h:19
#define c_blue
Definition: color.h:23
#define c_magenta
Definition: color.h:25
#define c_dark_gray
Definition: color.h:20
#define c_pink
Definition: color.h:31
#define c_light_blue
Definition: color.h:29
#define c_yellow
Definition: color.h:32
#define c_red
Definition: color.h:21
@ AEP_INVISIBLE
Definition: enums.h:110

References AEP_INVISIBLE, bio_cloak, c_blue, c_dark_gray, c_light_blue, c_light_gray, c_magenta, c_pink, c_red, c_white, c_yellow, CMM_CROUCH, CMM_RUN, effect_boomered, effect_onfire, effect_stunned, has_active_bionic(), has_active_mutation(), has_artifact_with(), Creature::has_effect(), has_trait(), Creature::is_underwater(), is_wearing_active_optcloak(), move_mode, trait_DEBUG_CLOAK, and trait_id.

Referenced by symbol_color().

◆ best_nearby_lifting_assist() [1/2]

int Character::best_nearby_lifting_assist ( ) const

Checks for items, tools, and vehicles with the Lifting quality near the character returning the highest quality in range.

Definition at line 2517 of file character.cpp.

2518{
2519 return best_nearby_lifting_assist( this->pos() );
2520}
int best_nearby_lifting_assist() const
Checks for items, tools, and vehicles with the Lifting quality near the character returning the highe...
Definition: character.cpp:2517

References best_nearby_lifting_assist(), and pos().

Referenced by best_nearby_lifting_assist(), can_do_activity_there(), and weight_carried_reduced_by().

◆ best_nearby_lifting_assist() [2/2]

int Character::best_nearby_lifting_assist ( const tripoint world_pos) const

Alternate version if you need to specify a different orign point for nearby vehicle sources of lifting used for operations on distant objects (e.g.

vehicle installation/uninstallation)

Definition at line 2522 of file character.cpp.

2523{
2524 const quality_id LIFT( "LIFT" );
2525 int mech_lift = 0;
2526 if( is_mounted() ) {
2527 auto mons = mounted_creature.get();
2528 if( mons->has_flag( MF_RIDEABLE_MECH ) ) {
2529 mech_lift = mons->mech_str_addition() + 10;
2530 }
2531 }
2532 return std::max( { this->max_quality( LIFT ), mech_lift,
2533 map_selector( this->pos(), PICKUP_RANGE, false ).max_quality( LIFT ),
2534 vehicle_selector( world_pos, PICKUP_RANGE, false ).max_quality( LIFT )
2535 } );
2536}
int PICKUP_RANGE
Items on the map with at most this distance to the player are considered available for crafting,...
shared_ptr_fast< monster > mounted_creature
Definition: character.h:1581
int max_quality(const quality_id &qual) const
Return maximum tool quality level provided by instance or INT_MIN if not found.
Definition: visitable.cpp:276
@ MF_RIDEABLE_MECH
Definition: mtype.h:115

References is_mounted(), visitable< T >::max_quality(), visitable< Character >::max_quality(), MF_RIDEABLE_MECH, mounted_creature, PICKUP_RANGE, and pos().

◆ best_quality_item()

item * Character::best_quality_item ( const quality_id qual)

get best quality item that this character has

Definition at line 4707 of file character.cpp.

4708{
4709 std::vector<item *> qual_inv = items_with( [qual]( const item & itm ) {
4710 return itm.has_quality( qual );
4711 } );
4712 item *best_qual = random_entry( qual_inv );
4713 for( const auto elem : qual_inv ) {
4714 if( elem->get_quality( qual ) > best_qual->get_quality( qual ) ) {
4715 best_qual = elem;
4716 }
4717 }
4718 return best_qual;
4719}
bool has_quality(const quality_id &qual, int level=1, int qty=1) const
Returns true if instance has amount (or more) items of at least quality level.
Definition: visitable.cpp:169
V random_entry(const C &container, D default_value)
Returns a random entry in the container.
Definition: rng.h:88

References visitable< T >::has_quality(), visitable< Character >::items_with(), and random_entry().

Referenced by chop_plank_activity(), chop_tree_activity(), generic_multi_activity_do(), and monexamine::shear_animal().

◆ best_shield()

item & Character::best_shield ( )

Returns the best item for blocking with.

Definition at line 1546 of file melee.cpp.

1547{
1548 // Note: wielded weapon, not one used for attacks
1549 int best_value = blocking_ability( weapon );
1550 // "BLOCK_WHILE_WORN" without a blocking tech need to be worn for the bonus
1551 best_value = best_value == 2 ? 0 : best_value;
1552 item *best = best_value > 0 ? &weapon : &null_item_reference();
1553 for( item &shield : worn ) {
1554 if( shield.has_flag( "BLOCK_WHILE_WORN" ) && blocking_ability( shield ) >= best_value ) {
1555 // in case a mod adds a shield that protects only one arm, the corresponding arm needs to be working
1556 if( shield.covers( bp_arm_l ) || shield.covers( bp_arm_r ) ) {
1557 if( shield.covers( bp_arm_l ) && !is_limb_disabled( bodypart_id( "arm_l" ) ) ) {
1558 best = &shield;
1559 } else if( shield.covers( bp_arm_r ) && !is_limb_disabled( bodypart_id( "arm_r" ) ) ) {
1560 best = &shield;
1561 }
1562 // leg guards
1563 } else if( ( shield.covers( bp_leg_l ) || shield.covers( bp_leg_r ) ) &&
1564 get_working_leg_count() >= 1 ) {
1565 best = &shield;
1566 // in case a mod adds an unusual worn blocking item, like a magic bracelet/crown, it's handled here
1567 } else {
1568 best = &shield;
1569 }
1570 }
1571 }
1572
1573 return *best;
1574}
int get_working_leg_count() const
Returns the number of functioning legs.
Definition: character.cpp:1226
bool is_limb_disabled(const bodypart_id &limb) const
Returns true if the limb is disabled(12.5% or less hp)
Definition: character.cpp:1238
item & null_item_reference()
Returns a reference to a null item (see item::is_null).
Definition: item.cpp:322
static int blocking_ability(const item &shield)
Definition: melee.cpp:1531

References blocking_ability(), bp_arm_l, bp_arm_r, bp_leg_l, bp_leg_r, get_working_leg_count(), is_limb_disabled(), null_item_reference(), weapon, and worn.

Referenced by block_hit().

◆ bionic_armor_bonus()

float Character::bionic_armor_bonus ( const bodypart_id bp,
damage_type  dt 
) const

Check for passive bionics that provide armor, and returns the armor bonus This is called from player::passive_absorb_hit.

Definition at line 8178 of file character.cpp.

8179{
8180 float result = 0.0f;
8181 if( dt == DT_CUT || dt == DT_STAB ) {
8182 for( const bionic_id &bid : get_bionics() ) {
8183 const auto cut_prot = bid->cut_protec.find( bp.id() );
8184 if( cut_prot != bid->cut_protec.end() ) {
8185 result += cut_prot->second;
8186 }
8187 }
8188 } else if( dt == DT_BASH ) {
8189 for( const bionic_id &bid : get_bionics() ) {
8190 const auto bash_prot = bid->bash_protec.find( bp.id() );
8191 if( bash_prot != bid->bash_protec.end() ) {
8192 result += bash_prot->second;
8193 }
8194 }
8195 } else if( dt == DT_BULLET ) {
8196 for( const bionic_id &bid : get_bionics() ) {
8197 const auto bullet_prot = bid->bullet_protec.find( bp.id() );
8198 if( bullet_prot != bid->bullet_protec.end() ) {
8199 result += bullet_prot->second;
8200 }
8201 }
8202 }
8203
8204 return result;
8205}
std::vector< bionic_id > get_bionics() const
Definition: character.cpp:1775
const string_id< T > & id() const
Definition: ammo_effect.cpp:33

References bionic_data::bash_protec, bionic_data::bullet_protec, bionic_data::cut_protec, DT_BASH, DT_BULLET, DT_CUT, DT_STAB, get_bionics(), and int_id< T >::id().

Referenced by passive_absorb_hit().

◆ bionic_installation_issues()

std::map< bodypart_id, int > Character::bionic_installation_issues ( const bionic_id bioid) const

Definition at line 2494 of file bionics.cpp.

2495{
2496 std::map<bodypart_id, int> issues;
2497 if( !get_option < bool >( "CBM_SLOTS_ENABLED" ) ) {
2498 return issues;
2499 }
2500 for( const std::pair<const bodypart_str_id, int> &elem : bioid->occupied_bodyparts ) {
2501 const int lacked_slots = elem.second - get_free_bionics_slots( elem.first );
2502 if( lacked_slots > 0 ) {
2503 issues.emplace( elem.first, lacked_slots );
2504 }
2505 }
2506 return issues;
2507}
int get_free_bionics_slots(const bodypart_id &bp) const
Definition: bionics.cpp:2514
std::map< bodypart_str_id, int > occupied_bodyparts
Body part slots used to install this bionic, mapped to the amount of space required.
Definition: bionics.h:91

References get_free_bionics_slots(), and bionic_data::occupied_bodyparts.

Referenced by can_install_bionics(), and item::color_in_inventory().

◆ bionics_adjusted_skill()

float Character::bionics_adjusted_skill ( const skill_id most_important_skill,
const skill_id important_skill,
const skill_id least_important_skill,
int  skill_level = -1 
)

Calculate skill for (un)installing bionics.

Definition at line 1840 of file bionics.cpp.

1844{
1845 int pl_skill = bionics_pl_skill( most_important_skill, important_skill, least_important_skill,
1846 skill_level );
1847
1848 // for chance_of_success calculation, shift skill down to a float between ~0.4 - 30
1849 float adjusted_skill = static_cast<float>( pl_skill ) - std::min( static_cast<float>( 40 ),
1850 static_cast<float>( pl_skill ) - static_cast<float>( pl_skill ) / static_cast<float>( 10.0 ) );
1851 adjusted_skill *= env_surgery_bonus( 1 ) + get_effect_int( effect_assisted );
1852 return adjusted_skill;
1853}
static const efftype_id effect_assisted("assisted")
float env_surgery_bonus(int radius)
Calculate skill bonus from tiles in radius.
Definition: bionics.cpp:2226
int bionics_pl_skill(const skill_id &most_important_skill, const skill_id &important_skill, const skill_id &least_important_skill, int skill_level=-1)
Calculate non adjusted skill for (un)installing bionics.
Definition: bionics.cpp:1855
int get_effect_int(const efftype_id &eff_id, body_part bp=num_bp) const
Returns the intensity of the matching effect.
Definition: creature.cpp:1256

References bionics_pl_skill(), effect_assisted, env_surgery_bonus(), and Creature::get_effect_int().

Referenced by best_installer(), can_install_bionics(), can_uninstall_bionic(), bionic_install_preset::get_failure_chance(), bionic_install_surgeon_preset::get_failure_chance(), bionic_uninstall_preset::get_failure_chance(), install_bionics(), game::save_cyborg(), and uninstall_bionic().

◆ bionics_install_failure()

void Character::bionics_install_failure ( const std::string &  installer,
int  difficulty,
int  success,
float  adjusted_skill 
)

Definition at line 2387 of file bionics.cpp.

2389{
2390 // "success" should be passed in as a negative integer representing how far off we
2391 // were for a successful install. We use this to determine consequences for failing.
2392 success = std::abs( success );
2393
2394 // failure level is decided by how far off the character was from a successful install, and
2395 // this is scaled up or down by the ratio of difficulty/skill. At high skill levels (or low
2396 // difficulties), only minor consequences occur. At low skill levels, severe consequences
2397 // are more likely.
2398 int failure_level = static_cast<int>( std::sqrt( success * 4.0 * difficulty / adjusted_skill ) );
2399 int fail_type = ( failure_level > 5 ? 5 : failure_level );
2400
2401 if( installer != "NOT_MED" ) {
2402 //~"Complications" is USian medical-speak for "unintended damage from a medical procedure".
2403 add_msg( m_neutral, _( "%s training helps to minimize the complications." ),
2404 installer );
2405 // In addition to the bonus, medical residents know enough OR protocol to avoid botching.
2406 // Take MD and be immune to faulty bionics.
2407 if( fail_type > 3 ) {
2408 fail_type = rng( 1, 3 );
2409 }
2410 }
2411
2412 switch( fail_type ) {
2413 case 0:
2414 case 1:
2416 break;
2417 case 2:
2418 case 3:
2419 do_damage_for_bionic_failure( 5, difficulty * 5 );
2420 break;
2421 case 4:
2422 case 5: {
2423 std::vector<bionic_id> valid;
2424 std::copy_if( begin( faulty_bionics ), end( faulty_bionics ), std::back_inserter( valid ),
2425 [&]( const bionic_id & id ) {
2426 return !has_bionic( id );
2427 } );
2428
2429 // We've got all the bad bionics!
2430 if( valid.empty() ) {
2431 if( has_max_power() ) {
2432 units::energy old_power = get_max_power_level();
2433 add_msg( m_bad, _( "%s lose power capacity!" ), disp_name() );
2438 }
2439 if( is_player() ) {
2440 g->memorial().add(
2441 pgettext( "memorial_male", "Lost %d units of power capacity." ),
2442 pgettext( "memorial_female", "Lost %d units of power capacity." ),
2443 units::to_kilojoule( old_power - get_max_power_level() ) );
2444 }
2445 // If no faults available and no power capacity, downgrade to second-worst complication.
2446 } else {
2447 do_damage_for_bionic_failure( 5, difficulty * 5 );
2448 break;
2449 }
2450 } else {
2451 const bionic_id &id = random_entry( valid );
2452 add_bionic( id );
2453 g->events().send<event_type::installs_faulty_cbm>( getID(), id );
2454 add_msg( m_bad,
2455 _( "Complication in installation caused a malfunction - %s. Uninstall it to clear the malfunction." ),
2456 id.obj().name );
2457 }
2458 }
2459 break;
2460 }
2461
2462}
bool has_max_power() const
Definition: character.cpp:1932
void set_max_power_level(const units::energy &npower_max)
Definition: character.cpp:1900
void do_damage_for_bionic_failure(int min_damage, int max_damage)
Definition: bionics.cpp:2347
@ installs_faulty_cbm
std::vector< bionic_id > faulty_bionics
Definition: bionics.cpp:214
const char * pgettext(const char *context, const char *msgid)

References _, add_bionic(), add_msg(), disp_name(), do_damage_for_bionic_failure(), anonymous_namespace{bionics.cpp}::faulty_bionics, units::from_kilojoule(), g, get_max_power_level(), getID(), has_bionic(), has_max_power(), id, installs_faulty_cbm, Creature::is_player(), m_bad, m_neutral, name, pgettext(), random_entry(), rng(), set_max_power_level(), behavior::success, and units::to_kilojoule().

Referenced by perform_install().

◆ bionics_pl_skill()

int Character::bionics_pl_skill ( const skill_id most_important_skill,
const skill_id important_skill,
const skill_id least_important_skill,
int  skill_level = -1 
)

Calculate non adjusted skill for (un)installing bionics.

Definition at line 1855 of file bionics.cpp.

1858{
1859 int pl_skill;
1860 if( skill_level == -1 ) {
1861 pl_skill = int_cur * 4 +
1862 get_skill_level( most_important_skill ) * 4 +
1863 get_skill_level( important_skill ) * 3 +
1864 get_skill_level( least_important_skill ) * 1;
1865 } else {
1866 // override chance as though all values were skill_level if it is provided
1867 pl_skill = 12 * skill_level;
1868 }
1869
1870 // Medical residents have some idea what they're doing
1871 if( has_trait( trait_PROF_MED ) ) {
1872 pl_skill += 3;
1873 }
1874
1875 // People trained in bionics gain an additional advantage towards using it
1876 if( has_trait( trait_PROF_AUTODOC ) ) {
1877 pl_skill += 7;
1878 }
1879 return pl_skill;
1880}
static const trait_id trait_PROF_MED("PROF_MED")
static const trait_id trait_PROF_AUTODOC("PROF_AUTODOC")

References get_skill_level(), has_trait(), int_cur, trait_PROF_AUTODOC, and trait_PROF_MED.

Referenced by bionics_adjusted_skill(), install_bionics(), and uninstall_bionic().

◆ bionics_uninstall_failure() [1/2]

void Character::bionics_uninstall_failure ( int  difficulty,
int  success,
float  adjusted_skill 
)

When a player fails the surgery.

Definition at line 1731 of file bionics.cpp.

1732{
1733 // "success" should be passed in as a negative integer representing how far off we
1734 // were for a successful removal. We use this to determine consequences for failing.
1735 success = std::abs( success );
1736
1737 // failure level is decided by how far off the character was from a successful removal, and
1738 // this is scaled up or down by the ratio of difficulty/skill. At high skill levels (or low
1739 // difficulties), only minor consequences occur. At low skill levels, severe consequences
1740 // are more likely.
1741 const int failure_level = static_cast<int>( std::sqrt( success * 4.0 * difficulty /
1742 adjusted_skill ) );
1743 const int fail_type = std::min( 5, failure_level );
1744
1745 if( fail_type <= 1 ) {
1746 add_msg( m_neutral, _( "The removal fails without incident." ) );
1747 return;
1748 }
1749
1750 add_msg( m_neutral, _( "The removal is a failure." ) );
1751 std::set<body_part> bp_hurt;
1752 switch( fail_type ) {
1753 case 2:
1754 case 3:
1756 break;
1757
1758 case 4:
1759 case 5:
1760 do_damage_for_bionic_failure( 5, difficulty * 5 );
1761 break;
1762 }
1763
1764}

References _, add_msg(), do_damage_for_bionic_failure(), m_neutral, and behavior::success.

Referenced by perform_uninstall(), and uninstall_bionic().

◆ bionics_uninstall_failure() [2/2]

void Character::bionics_uninstall_failure ( monster installer,
player patient,
int  difficulty,
int  success,
float  adjusted_skill 
)

When a monster fails the surgery.

Definition at line 1766 of file bionics.cpp.

1768{
1769
1770 // "success" should be passed in as a negative integer representing how far off we
1771 // were for a successful removal. We use this to determine consequences for failing.
1772 success = std::abs( success );
1773
1774 // failure level is decided by how far off the monster was from a successful removal, and
1775 // this is scaled up or down by the ratio of difficulty/skill. At high skill levels (or low
1776 // difficulties), only minor consequences occur. At low skill levels, severe consequences
1777 // are more likely.
1778 const int failure_level = static_cast<int>( std::sqrt( success * 4.0 * difficulty /
1779 adjusted_skill ) );
1780 const int fail_type = std::min( 5, failure_level );
1781
1782 bool u_see = sees( patient );
1783
1784 if( u_see || patient.is_player() ) {
1785 if( fail_type <= 1 ) {
1786 add_msg( m_neutral, _( "The removal fails without incident." ) );
1787 return;
1788 }
1789 switch( rng( 1, 5 ) ) {
1790 case 1:
1791 add_msg( m_mixed, _( "The %s flub the operation." ), installer.name() );
1792 break;
1793 case 2:
1794 add_msg( m_mixed, _( "The %s messes up the operation." ), installer.name() );
1795 break;
1796 case 3:
1797 add_msg( m_mixed, _( "The operation fails." ) );
1798 break;
1799 case 4:
1800 add_msg( m_mixed, _( "The operation is a failure." ) );
1801 break;
1802 case 5:
1803 add_msg( m_mixed, _( "The %s screws up the operation." ), installer.name() );
1804 break;
1805 }
1806 }
1807 switch( fail_type ) {
1808 case 2:
1809 case 3:
1810 do_damage_for_bionic_failure( failure_level, failure_level * 2 );
1811 break;
1812
1813 case 4:
1814 case 5:
1815 do_damage_for_bionic_failure( 5, difficulty * 5 );
1816 break;
1817 }
1818}
bool sees(const tripoint &t, bool is_player=false, int range_mod=0) const override
std::string name(unsigned int quantity=1) const
Definition: monster.cpp:493
bool is_player() const override
Definition: player.h:93

References _, add_msg(), do_damage_for_bionic_failure(), player::is_player(), m_mixed, m_neutral, monster::name(), rng(), sees(), and behavior::success.

◆ bionics_weight()

units::mass Character::bionics_weight ( ) const

Definition at line 6723 of file character.cpp.

6724{
6725 units::mass bio_weight = 0_gram;
6726 for( const bionic_id &bid : get_bionics() ) {
6727 if( !bid->included ) {
6728 bio_weight += bid->itype()->weight;
6729 }
6730 }
6731 return bio_weight;
6732}

References get_bionics().

Referenced by get_weight().

◆ block_hit()

bool Character::block_hit ( Creature source,
bodypart_id bp_hit,
damage_instance dam 
)
overridevirtual

Checks for valid block abilities and reduces damage accordingly.

Returns true if the player blocks

Strength increases attack blocking effectiveness with a limb or worn/wielded item Unarmed increases attack blocking effectiveness with a limb or worn/wielded item

Implements Creature.

Definition at line 1576 of file melee.cpp.

1577{
1578 // Shouldn't block if player is asleep
1580 return false;
1581 }
1582
1583 // fire martial arts on-getting-hit-triggered effects
1584 // these fire even if the attack is blocked (you still got hit)
1585 martial_arts_data->ma_ongethit_effects( *this );
1586
1587 if( blocks_left < 1 ) {
1588 return false;
1589 }
1590
1591 blocks_left--;
1592
1593 // This bonus absorbs damage from incoming attacks before they land,
1594 // but it still counts as a block even if it absorbs all the damage.
1595 float total_phys_block = mabuff_block_bonus();
1596
1597 // Extract this to make it easier to implement shields/multiwield later
1598 item &shield = best_shield();
1599 block_bonus = blocking_ability( shield );
1600 bool conductive_shield = shield.conductive();
1601 bool unarmed = weapon.has_flag( "UNARMED_WEAPON" ) || weapon.is_null();
1602 bool force_unarmed = martial_arts_data->is_force_unarmed();
1603
1604 int melee_skill = get_skill_level( skill_melee );
1605 int unarmed_skill = get_skill_level( skill_unarmed );
1606
1607 // Check if we are going to block with an item. This could
1608 // be worn equipment with the BLOCK_WHILE_WORN flag.
1609 const bool has_shield = !shield.is_null();
1610
1611 // boolean check if blocking is being done with unarmed or not
1612 const bool item_blocking = !force_unarmed && has_shield && !unarmed;
1613
1614 int block_score = 1;
1615
1616 /** @EFFECT_STR increases attack blocking effectiveness with a limb or worn/wielded item */
1617 /** @EFFECT_UNARMED increases attack blocking effectiveness with a limb or worn/wielded item */
1618 if( ( unarmed || force_unarmed ) ) {
1619 if( martial_arts_data->can_limb_block( *this ) ) {
1620 // block_bonus for limb blocks will be added when the limb is decided
1621 block_score = str_cur + melee_skill + unarmed_skill;
1622 } else if( has_shield ) {
1623 // We can still block with a worn item while unarmed. Use higher of melee and unarmed
1624 block_score = str_cur + block_bonus + std::max( melee_skill, unarmed_skill );
1625 }
1626 } else if( has_shield ) {
1627 block_score = str_cur + block_bonus + get_skill_level( skill_melee );
1628 } else {
1629 // Can't block with limbs or items (do not block)
1630 return false;
1631 }
1632
1633 // weapon blocks are preferred to limb blocks
1634 std::string thing_blocked_with;
1635 if( !force_unarmed && has_shield ) {
1636 thing_blocked_with = shield.tname();
1637 // TODO: Change this depending on damage blocked
1638 float wear_modifier = 1.0f;
1639 if( source != nullptr && source->is_hallucination() ) {
1640 wear_modifier = 0.0f;
1641 }
1642
1643 handle_melee_wear( shield, wear_modifier );
1644 } else {
1645 // Choose which body part to block with, assume left side first
1646 if( martial_arts_data->can_leg_block( *this ) && martial_arts_data->can_arm_block( *this ) ) {
1647 bp_hit = one_in( 2 ) ? bodypart_id( "leg_l" ) : bodypart_id( "arm_l" );
1648 } else if( martial_arts_data->can_leg_block( *this ) ) {
1649 bp_hit = bodypart_id( "leg_l" );
1650 } else {
1651 bp_hit = bodypart_id( "arm_l" );
1652 }
1653
1654 // Check if we should actually use the right side to block
1655 if( bp_hit == bodypart_id( "leg_l" ) ) {
1656 if( get_part_hp_cur( bodypart_id( "leg_r" ) ) > get_part_hp_cur( bodypart_id( "leg_l" ) ) ) {
1657 bp_hit = bodypart_id( "leg_r" );
1658 }
1659 } else {
1660 if( get_part_hp_cur( bodypart_id( "arm_r" ) ) > get_part_hp_cur( bodypart_id( "arm_l" ) ) ) {
1661 bp_hit = bodypart_id( "arm_r" );
1662 }
1663 }
1664
1665 // At this point, we know we won't try blocking with items, only with limbs.
1666 // But there are no limbs left, so we can disable further attempts at blocking.
1667 if( get_part_hp_cur( bp_hit ) <= 0 ) {
1668 blocks_left = 0;
1669 return false;
1670 }
1671
1672 thing_blocked_with = body_part_name( bp_hit->token );
1673 }
1674
1675 if( has_shield ) {
1676 // Does our shield cover the limb we blocked with? If so, add the block bonus.
1677 block_score += shield.covers( bp_hit->token ) ? block_bonus : 0;
1678 }
1679
1680 // Map block_score to the logistic curve for a number between 1 and 0.
1681 // Basic beginner character (str 8, skill 0, basic weapon)
1682 // Will have a score around 10 and block about %15 of incoming damage.
1683 // More proficient melee character (str 10, skill 4, wbock_2 weapon)
1684 // will have a score of 20 and block about 45% of damage.
1685 // A highly expert character (str 14, skill 8 wblock_2)
1686 // will have a score in the high 20s and will block about 80% of damage.
1687 // As the block score approaches 40, damage making it through will dwindle
1688 // to nothing, at which point we're relying on attackers hitting enough to drain blocks.
1689 const float physical_block_multiplier = logarithmic_range( 0, 40, block_score );
1690
1691 float total_damage = 0.0;
1692 float damage_blocked = 0.0;
1693
1694 for( auto &elem : dam.damage_units ) {
1695 total_damage += elem.amount;
1696
1697 // block physical damage "normally"
1698 if( elem.type == DT_BASH || elem.type == DT_CUT || elem.type == DT_STAB ) {
1699 // use up our flat block bonus first
1700 float block_amount = std::min( total_phys_block, elem.amount );
1701 total_phys_block -= block_amount;
1702 elem.amount -= block_amount;
1703 damage_blocked += block_amount;
1704
1705 if( elem.amount <= std::numeric_limits<float>::epsilon() ) {
1706 continue;
1707 }
1708
1709 float previous_amount = elem.amount;
1710 elem.amount *= physical_block_multiplier;
1711 damage_blocked += previous_amount - elem.amount;
1712 }
1713
1714 // non-electrical "elemental" damage types do their full damage if unarmed,
1715 // but severely mitigated damage if not
1716 else if( elem.type == DT_HEAT || elem.type == DT_ACID || elem.type == DT_COLD ) {
1717 // Unarmed weapons won't block those
1718 if( item_blocking ) {
1719 float previous_amount = elem.amount;
1720 elem.amount /= 5;
1721 damage_blocked += previous_amount - elem.amount;
1722 }
1723 // electrical damage deals full damage if unarmed OR wielding a
1724 // conductive weapon
1725 } else if( elem.type == DT_ELECTRIC ) {
1726 // Unarmed weapons and conductive weapons won't block this
1727 if( item_blocking && !conductive_shield ) {
1728 float previous_amount = elem.amount;
1729 elem.amount /= 5;
1730 damage_blocked += previous_amount - elem.amount;
1731 }
1732 }
1733 }
1734
1735 std::string damage_blocked_description;
1736 // good/bad/ugly add_msg color code?
1737 // none, hardly any, a little, some, most, all
1738 float blocked_ratio = 0.0f;
1739 if( total_damage > std::numeric_limits<float>::epsilon() ) {
1740 blocked_ratio = ( total_damage - damage_blocked ) / total_damage;
1741 }
1742 if( blocked_ratio < std::numeric_limits<float>::epsilon() ) {
1743 //~ Damage amount in "You block <damage amount> with your <weapon>."
1744 damage_blocked_description = pgettext( "block amount", "all of the damage" );
1745 } else if( blocked_ratio < 0.2 ) {
1746 //~ Damage amount in "You block <damage amount> with your <weapon>."
1747 damage_blocked_description = pgettext( "block amount", "nearly all of the damage" );
1748 } else if( blocked_ratio < 0.4 ) {
1749 //~ Damage amount in "You block <damage amount> with your <weapon>."
1750 damage_blocked_description = pgettext( "block amount", "most of the damage" );
1751 } else if( blocked_ratio < 0.6 ) {
1752 //~ Damage amount in "You block <damage amount> with your <weapon>."
1753 damage_blocked_description = pgettext( "block amount", "a lot of the damage" );
1754 } else if( blocked_ratio < 0.8 ) {
1755 //~ Damage amount in "You block <damage amount> with your <weapon>."
1756 damage_blocked_description = pgettext( "block amount", "some of the damage" );
1757 } else if( blocked_ratio > std::numeric_limits<float>::epsilon() ) {
1758 //~ Damage amount in "You block <damage amount> with your <weapon>."
1759 damage_blocked_description = pgettext( "block amount", "a little of the damage" );
1760 } else {
1761 //~ Damage amount in "You block <damage amount> with your <weapon>."
1762 damage_blocked_description = pgettext( "block amount", "none of the damage" );
1763 }
1765 //~ %1$s is damage amount string (e.g. "most of the damage"), %2$s is weapon name
1766 _( "You block %1$s with your %2$s!" ),
1767 //~ %1$s is damage amount string (e.g. "most of the damage"), %2$s is weapon name
1768 _( "<npcname> blocks %1$s with their %2$s!" ),
1769 damage_blocked_description, thing_blocked_with );
1770
1771 // fire martial arts block-triggered effects
1772 martial_arts_data->ma_onblock_effects( *this );
1773
1774 // Check if we have any block counters
1775 matec_id tec = pick_technique( *source, shield, false, false, true );
1776
1777 if( tec != tec_none && !is_dead_state() ) {
1778 if( get_stamina() < get_stamina_max() / 3 ) {
1779 add_msg( m_bad, _( "You try to counterattack but you are too exhausted!" ) );
1780 } else if( weapon.made_of( material_id( "glass" ) ) ) {
1781 add_msg( m_bad, _( "The item you are wielding is too fragile to counterattack with!" ) );
1782 } else {
1783 melee_attack( *source, false, &tec );
1784 }
1785 }
1786
1787 return true;
1788}
std::string body_part_name(body_part bp, int number)
Returns the matching name of the body_part token.
Definition: bodypart.cpp:317
double logarithmic_range(int min, int max, int pos)
Normalized logistic function.
int blocks_left
Definition: character.h:560
matec_id pick_technique(Creature &t, const item &weap, bool crit, bool dodge_counter, bool block_counter)
Returns a random valid technique.
Definition: melee.cpp:1117
int mabuff_block_bonus() const
Returns the block bonus from martial arts buffs.
bool in_sleep_state() const override
Definition: character.cpp:9276
void melee_attack(Creature &t, bool allow_special, const matec_id *force_technique=nullptr, bool allow_unarmed=true)
Sets up a melee attack and handles melee attack function calls.
Definition: melee.cpp:387
bool handle_melee_wear(item &shield, float wear_multiplier=1.0f)
Calculates melee weapon wear-and-tear through use, returns true if item is destroyed.
Definition: melee.cpp:159
item & best_shield()
Returns the best item for blocking with.
Definition: melee.cpp:1546
virtual bool is_hallucination() const =0
virtual void add_msg_player_or_npc(const std::string &, const std::string &) const
Definition: creature.h:681
int block_bonus
Definition: creature.h:831
bool conductive() const
Whether the items is conductive.
Definition: item.cpp:6483
const std::vector< material_id > & made_of() const
The ids of all the materials this is made of.
Definition: item.cpp:6418
@ DT_COLD
Definition: damage.h:29
@ DT_ELECTRIC
Definition: damage.h:30
@ DT_ACID
Definition: damage.h:26
static const efftype_id effect_narcosis("narcosis")
static const matec_id tec_none("tec_none")
static const skill_id skill_unarmed("unarmed")

References _, add_msg(), Creature::add_msg_player_or_npc(), best_shield(), Creature::block_bonus, blocking_ability(), blocks_left, body_part_name(), item::conductive(), item::covers(), damage_instance::damage_units, DT_ACID, DT_BASH, DT_COLD, DT_CUT, DT_ELECTRIC, DT_HEAT, DT_STAB, effect_narcosis, Creature::get_part_hp_cur(), get_skill_level(), get_stamina(), get_stamina_max(), handle_melee_wear(), Creature::has_effect(), item::has_flag(), in_sleep_state(), is_dead_state(), Creature::is_hallucination(), item::is_null(), logarithmic_range(), m_bad, mabuff_block_bonus(), item::made_of(), martial_arts_data, melee_attack(), one_in(), pgettext(), pick_technique(), skill_melee, skill_unarmed, str_cur, tec_none, item::tname(), and weapon.

◆ blood_loss()

int Character::blood_loss ( const bodypart_id bp) const

Define blood loss (in percents)

Definition at line 5683 of file character.cpp.

5684{
5685 int hp_cur_sum = get_part_hp_cur( bp );
5686 int hp_max_sum = get_part_hp_max( bp );
5687
5688 if( bp == bodypart_id( "leg_l" ) || bp == bodypart_id( "leg_r" ) ) {
5689 hp_cur_sum = get_part_hp_cur( bodypart_id( "leg_l" ) ) + get_part_hp_cur( bodypart_id( "leg_r" ) );
5690 hp_max_sum = get_part_hp_max( bodypart_id( "leg_l" ) ) + get_part_hp_max( bodypart_id( "leg_r" ) );
5691 } else if( bp == bodypart_id( "arm_l" ) || bp == bodypart_id( "arm_r" ) ) {
5692 hp_cur_sum = get_part_hp_cur( bodypart_id( "arm_l" ) ) + get_part_hp_cur( bodypart_id( "arm_r" ) );
5693 hp_max_sum = get_part_hp_max( bodypart_id( "arm_l" ) ) + get_part_hp_max( bodypart_id( "arm_r" ) );
5694 }
5695
5696 hp_cur_sum = std::min( hp_max_sum, std::max( 0, hp_cur_sum ) );
5697 hp_max_sum = std::max( hp_max_sum, 1 );
5698 return 100 - ( 100 * hp_cur_sum ) / hp_max_sum;
5699}
int get_part_hp_max(const bodypart_id &id) const
Definition: creature.cpp:1571

References Creature::get_part_hp_cur(), and Creature::get_part_hp_max().

◆ bloodType()

field_type_id Character::bloodType ( ) const
overridevirtual

Implements Creature.

Definition at line 494 of file character.cpp.

495{
496 if( has_trait( trait_ACIDBLOOD ) ) {
497 return fd_acid;
498 }
500 return fd_blood_veggy;
501 }
503 return fd_blood_insect;
504 }
507 }
508 return fd_blood;
509}
static const trait_id trait_THRESH_CEPHALOPOD("THRESH_CEPHALOPOD")
static const trait_id trait_THRESH_PLANT("THRESH_PLANT")
static const trait_id trait_THRESH_INSECT("THRESH_INSECT")
static const trait_id trait_ACIDBLOOD("ACIDBLOOD")
static const trait_id trait_THRESH_SPIDER("THRESH_SPIDER")
field_type_id fd_blood_insect
Definition: field_type.cpp:363
field_type_id fd_blood_invertebrate
Definition: field_type.cpp:364
field_type_id fd_blood_veggy
Definition: field_type.cpp:362
field_type_id fd_blood
Definition: field_type.cpp:336
field_type_id fd_acid
Definition: field_type.cpp:342

References fd_acid, fd_blood, fd_blood_insect, fd_blood_invertebrate, fd_blood_veggy, has_trait(), trait_ACIDBLOOD, trait_THRESH_CEPHALOPOD, trait_THRESH_INSECT, trait_THRESH_PLANT, and trait_THRESH_SPIDER.

◆ blossoms()

void Character::blossoms ( )

Definition at line 8746 of file character.cpp.

8747{
8748 // Player blossoms are shorter-ranged, but you can fire much more frequently if you like.
8749 sounds::sound( pos(), 10, sounds::sound_t::combat, _( "Pouf!" ), false, "misc", "puff" );
8750 map &here = get_map();
8751 for( const tripoint &tmp : here.points_in_radius( pos(), 2 ) ) {
8752 here.add_field( tmp, fd_fungal_haze, rng( 1, 2 ) );
8753 }
8754}
field_type_id fd_fungal_haze
Definition: field_type.cpp:374

References _, map::add_field(), sounds::combat, fd_fungal_haze, get_map(), map::points_in_radius(), pos(), rng(), and sounds::sound().

Referenced by activate_mutation(), and suffer_while_awake().

◆ bmi()

float Character::bmi ( ) const

Definition at line 6713 of file character.cpp.

6714{
6715 return 25;
6716}

Referenced by bodyweight(), debug_menu::debug(), character_display::disp_info(), and suffer_mutation_power().

◆ bmr()

int Character::bmr ( ) const

Definition at line 6820 of file character.cpp.

6821{
6822 return metabolic_rate_base() * 2500;
6823}
float metabolic_rate_base() const
Stable base metabolic rate due to traits.

References metabolic_rate_base().

Referenced by debug_menu::debug(), fall_asleep(), get_hunger_description(), and update_stomach().

◆ body_window()

hp_part Character::body_window ( const std::string &  menu_header,
bool  show_all,
bool  precise,
int  normal_bonus,
int  head_bonus,
int  torso_bonus,
float  bleed,
float  bite,
float  infect,
float  bandage_power,
float  disinfectant_power 
) const

Displays menu with body part hp, optionally with hp estimation after healing.

Returns selected part. menu_header - name of item that triggers this menu show_all - show and enable choice of all limbs, not only healable precise - show numerical hp normal_bonus - heal normal limb head_bonus - heal head torso_bonus - heal torso bleed - chance to stop bleeding bite - chance to remove bite infect - chance to remove infection bandage_power - quality of bandage disinfectant_power - quality of disinfectant

Definition at line 5713 of file character.cpp.

5717{
5718 /* This struct establishes some kind of connection between the hp_part (which can be healed and
5719 * have HP) and the body_part. Note that there are more body_parts than hp_parts. For example:
5720 * Damage to bp_head, bp_eyes and bp_mouth is all applied on the HP of hp_head. */
5721 struct healable_bp {
5722 mutable bool allowed;
5723 bodypart_id bp;
5724 hp_part hp;
5725 std::string name; // Translated name as it appears in the menu.
5726 int bonus;
5727 };
5728 /* The array of the menu entries show to the player. The entries are displayed in this order,
5729 * it may be changed here. */
5730 std::array<healable_bp, num_hp_parts> parts = { {
5731 { false, bodypart_id( "head" ), hp_head, _( "Head" ), head_bonus },
5732 { false, bodypart_id( "torso" ), hp_torso, _( "Torso" ), torso_bonus },
5733 { false, bodypart_id( "arm_l" ), hp_arm_l, _( "Left Arm" ), normal_bonus },
5734 { false, bodypart_id( "arm_r" ), hp_arm_r, _( "Right Arm" ), normal_bonus },
5735 { false, bodypart_id( "leg_l" ), hp_leg_l, _( "Left Leg" ), normal_bonus },
5736 { false, bodypart_id( "leg_r" ), hp_leg_r, _( "Right Leg" ), normal_bonus },
5737 }
5738 };
5739
5740 int max_bp_name_len = 0;
5741 for( const auto &e : parts ) {
5742 max_bp_name_len = std::max( max_bp_name_len, utf8_width( e.name ) );
5743 }
5744
5745 uilist bmenu;
5746 bmenu.desc_enabled = true;
5747 bmenu.text = menu_header;
5748
5749 bmenu.hilight_disabled = true;
5750 bool is_valid_choice = false;
5751
5752 for( size_t i = 0; i < parts.size(); i++ ) {
5753 const auto &e = parts[i];
5754 const bodypart_id &bp = e.bp;
5755 const body_part bp_token = bp->token;
5756 const int maximal_hp = get_part_hp_max( bp );
5757 const int current_hp = get_part_hp_cur( bp );
5758 // This will c_light_gray if the part does not have any effects cured by the item/effect
5759 // (e.g. it cures only bites, but the part does not have a bite effect)
5760 const nc_color state_col = limb_color( bp, bleed > 0.0f, bite > 0.0f, infect > 0.0f );
5761 const bool has_curable_effect = state_col != c_light_gray;
5762 // The same as in the main UI sidebar. Independent of the capability of the healing item/effect!
5763 const nc_color all_state_col = limb_color( bp, true, true, true );
5764 // Broken means no HP can be restored, it requires surgical attention.
5765 const bool limb_is_broken = is_limb_broken( bp );
5766 const bool limb_is_mending = limb_is_broken && worn_with_flag( flag_SPLINT, bp );
5767
5768 if( show_all ) {
5769 e.allowed = true;
5770 } else if( has_curable_effect ) {
5771 e.allowed = true;
5772 } else if( limb_is_broken ) {
5773 e.allowed = false;
5774 } else if( current_hp < maximal_hp && ( e.bonus != 0 || bandage_power > 0.0f ||
5775 disinfectant_power > 0.0f ) ) {
5776 e.allowed = true;
5777 } else {
5778 e.allowed = false;
5779 }
5780
5781 std::string msg;
5782 std::string desc;
5783 bool bleeding = has_effect( effect_bleed, bp_token );
5784 bool bitten = has_effect( effect_bite, bp_token );
5785 bool infected = has_effect( effect_infected, bp_token );
5786 bool bandaged = has_effect( effect_bandaged, bp_token );
5787 bool disinfected = has_effect( effect_disinfected, bp_token );
5788 const int b_power = get_effect_int( effect_bandaged, bp_token );
5789 const int d_power = get_effect_int( effect_disinfected, bp_token );
5790 int new_b_power = static_cast<int>( std::floor( bandage_power ) );
5791 if( bandaged ) {
5792 const effect &eff = get_effect( effect_bandaged, bp_token );
5793 if( new_b_power > eff.get_max_intensity() ) {
5794 new_b_power = eff.get_max_intensity();
5795 }
5796
5797 }
5798 int new_d_power = static_cast<int>( std::floor( disinfectant_power ) );
5799
5800 const auto &aligned_name = std::string( max_bp_name_len - utf8_width( e.name ), ' ' ) + e.name;
5801 std::string hp_str;
5802 if( limb_is_mending ) {
5803 desc += colorize( _( "It is broken but has been set and just needs time to heal." ),
5804 c_blue ) + "\n";
5805 const auto &eff = get_effect( effect_mending, bp_token );
5806 const int mend_perc = eff.is_null() ? 0.0 : 100 * eff.get_duration() / eff.get_max_duration();
5807
5808 if( precise ) {
5809 hp_str = colorize( string_format( "=%2d%%=", mend_perc ), c_blue );
5810 } else {
5811 const int num = mend_perc / 20;
5812 hp_str = colorize( std::string( num, '#' ) + std::string( 5 - num, '=' ), c_blue );
5813 }
5814 } else if( limb_is_broken ) {
5815 desc += colorize( _( "It is broken. It needs a splint or surgical attention." ), c_red ) + "\n";
5816 hp_str = "==%==";
5817 } else if( precise ) {
5818 hp_str = string_format( "%d", current_hp );
5819 } else {
5820 std::pair<std::string, nc_color> h_bar = get_hp_bar( current_hp, maximal_hp, false );
5821 hp_str = colorize( h_bar.first, h_bar.second ) +
5822 colorize( std::string( 5 - utf8_width( h_bar.first ), '.' ), c_white );
5823 }
5824 msg += colorize( aligned_name, all_state_col ) + " " + hp_str;
5825
5826 // BLEEDING block
5827 if( bleeding ) {
5828 desc += colorize( string_format( "%s: %s", get_effect( effect_bleed, bp_token ).get_speed_name(),
5829 get_effect( effect_bleed, bp_token ).disp_short_desc() ), c_red ) + "\n";
5830 if( bleed > 0.0f ) {
5831 desc += colorize( string_format( _( "Chance to stop: %d %%" ),
5832 static_cast<int>( bleed * 100 ) ), c_light_green ) + "\n";
5833 } else {
5834 desc += colorize( _( "This will not stop the bleeding." ),
5835 c_yellow ) + "\n";
5836 }
5837 }
5838 // BANDAGE block
5839 if( bandaged ) {
5840 desc += string_format( _( "Bandaged [%s]" ), texitify_healing_power( b_power ) ) + "\n";
5841 if( new_b_power > b_power ) {
5842 desc += colorize( string_format( _( "Expected quality improvement: %s" ),
5843 texitify_healing_power( new_b_power ) ), c_light_green ) + "\n";
5844 } else if( new_b_power > 0 ) {
5845 desc += colorize( _( "You don't expect any improvement from using this." ), c_yellow ) + "\n";
5846 }
5847 } else if( new_b_power > 0 && e.allowed ) {
5848 desc += colorize( string_format( _( "Expected bandage quality: %s" ),
5849 texitify_healing_power( new_b_power ) ), c_light_green ) + "\n";
5850 }
5851 // BITTEN block
5852 if( bitten ) {
5853 desc += colorize( string_format( "%s: ", get_effect( effect_bite,
5854 bp_token ).get_speed_name() ), c_red );
5855 desc += colorize( _( "It has a deep bite wound that needs cleaning." ), c_red ) + "\n";
5856 if( bite > 0 ) {
5857 desc += colorize( string_format( _( "Chance to clean and disinfect: %d %%" ),
5858 static_cast<int>( bite * 100 ) ), c_light_green ) + "\n";
5859 } else {
5860 desc += colorize( _( "This will not help in cleaning this wound." ), c_yellow ) + "\n";
5861 }
5862 }
5863 // INFECTED block
5864 if( infected ) {
5866 bp_token ).get_speed_name() ), c_red );
5867 desc += colorize( _( "It has a deep wound that looks infected. Antibiotics might be required." ),
5868 c_red ) + "\n";
5869 if( infect > 0 ) {
5870 desc += colorize( string_format( _( "Chance to heal infection: %d %%" ),
5871 static_cast<int>( infect * 100 ) ), c_light_green ) + "\n";
5872 } else {
5873 desc += colorize( _( "This will not help in healing infection." ), c_yellow ) + "\n";
5874 }
5875 }
5876 // DISINFECTANT (general) block
5877 if( disinfected ) {
5878 desc += string_format( _( "Disinfected [%s]" ),
5879 texitify_healing_power( d_power ) ) + "\n";
5880 if( new_d_power > d_power ) {
5881 desc += colorize( string_format( _( "Expected quality improvement: %s" ),
5882 texitify_healing_power( new_d_power ) ), c_light_green ) + "\n";
5883 } else if( new_d_power > 0 ) {
5884 desc += colorize( _( "You don't expect any improvement from using this." ),
5885 c_yellow ) + "\n";
5886 }
5887 } else if( new_d_power > 0 && e.allowed ) {
5888 desc += colorize( string_format(
5889 _( "Expected disinfection quality: %s" ),
5890 texitify_healing_power( new_d_power ) ), c_light_green ) + "\n";
5891 }
5892 // END of blocks
5893
5894 if( ( !e.allowed && !limb_is_broken ) || ( show_all && current_hp == maximal_hp &&
5895 !limb_is_broken && !bitten && !infected && !bleeding ) ) {
5896 desc += colorize( _( "Healthy." ), c_green ) + "\n";
5897 }
5898 if( !e.allowed ) {
5899 desc += colorize( _( "You don't expect any effect from using this." ), c_yellow );
5900 } else {
5901 is_valid_choice = true;
5902 }
5903 bmenu.addentry_desc( i, e.allowed, MENU_AUTOASSIGN, msg, desc );
5904 }
5905
5906 if( !is_valid_choice ) { // no body part can be chosen for this item/effect
5907 bmenu.init();
5908 bmenu.desc_enabled = false;
5909 bmenu.text = _( "No limb would benefit from it." );
5910 bmenu.addentry( parts.size(), true, 'q', "%s", _( "Cancel" ) );
5911 }
5912
5913 bmenu.query();
5914 if( bmenu.ret >= 0 && static_cast<size_t>( bmenu.ret ) < parts.size() &&
5915 parts[bmenu.ret].allowed ) {
5916 return parts[bmenu.ret].hp;
5917 } else {
5918 return num_hp_parts;
5919 }
5920}
int utf8_width(const char *s, const bool ignore_tags)
static const efftype_id effect_bleed("bleed")
static const efftype_id effect_infected("infected")
static const efftype_id effect_bite("bite")
static const std::string flag_SPLINT("SPLINT")
bool worn_with_flag(const std::string &flag, const bodypart_id &bp=bodypart_str_id::NULL_ID()) const
Returns true if the player is wearing an item with the given flag.
Definition: character.cpp:3231
nc_color limb_color(const bodypart_id &bp, bool bleed, bool bite, bool infect) const
Definition: character.cpp:5922
bool is_limb_broken(const bodypart_id &limb) const
Returns true if the limb is broken.
Definition: character.cpp:1245
virtual void bleed() const
Adds an appropriate blood splatter.
Definition: creature.cpp:127
int get_max_intensity() const
Returns the maximum intensity of an effect.
Definition: effect.cpp:853
time_duration get_duration() const
Returns the remaining duration of an effect.
Definition: effect.cpp:797
bool is_null() const
Returns true if the effect is the result of effect(), ie.
Definition: effect.cpp:553
int ret
Definition: ui.h:412
bool desc_enabled
Definition: ui.h:352
void addentry_desc(const std::string &str, const std::string &desc)
Definition: ui.cpp:952
bool hilight_disabled
Definition: ui.h:366
std::string text
Definition: ui.h:320
void addentry(const std::string &str)
Definition: ui.cpp:942
#define c_green
Definition: color.h:22
#define c_light_green
Definition: color.h:28
std::string texitify_healing_power(const int power)
Definition: effect.cpp:1478
void query(bool loop=true, int timeout=-1)
Handle input and update display.
Definition: ui.cpp:838
void init()
Sane defaults on initialization.
Definition: ui.cpp:152
std::pair< std::string, nc_color > get_hp_bar(const int cur_hp, const int max_hp, const bool is_mon)
Definition: output.cpp:1604
hp_part
Definition: pldata.h:32
@ hp_torso
Definition: pldata.h:34
@ hp_leg_r
Definition: pldata.h:38
@ hp_arm_r
Definition: pldata.h:36
@ hp_head
Definition: pldata.h:33
@ hp_arm_l
Definition: pldata.h:35
@ num_hp_parts
Definition: pldata.h:39
@ hp_leg_l
Definition: pldata.h:37
@ hp
Drains HP to recharge.
const int MENU_AUTOASSIGN
Definition: ui.h:31

References _, uilist::addentry(), uilist::addentry_desc(), Creature::bleed(), c_blue, c_green, c_light_gray, c_light_green, c_red, c_white, c_yellow, colorize(), uilist::desc_enabled, effect_bandaged, effect_bite, effect_bleed, effect_disinfected, effect_infected, effect_mending, flag_SPLINT(), Creature::get_effect(), Creature::get_effect_int(), get_hp_bar(), effect::get_max_intensity(), Creature::get_part_hp_cur(), Creature::get_part_hp_max(), Creature::has_effect(), uilist::hilight_disabled, hp, hp_arm_l, hp_arm_r, hp_head, hp_leg_l, hp_leg_r, hp_torso, uilist::init(), is_limb_broken(), limb_color(), MENU_AUTOASSIGN, name, num, num_hp_parts, uilist::query(), uilist::ret, string_format(), texitify_healing_power(), uilist::text, utf8_width(), and worn_with_flag().

Referenced by game::npc_menu(), and pick_part_to_heal().

◆ bodypart_exposure()

std::map< bodypart_id, float > Character::bodypart_exposure ( )

Map body parts to their total exposure, from 0.0 (fully covered) to 1.0 (buck naked).

Clothing layers are multiplied, ex. two layers of 50% coverage will leave only 25% exposed. Used to determine suffering effects of albinism and solar sensitivity.

Definition at line 783 of file suffer.cpp.

784{
785 std::map<bodypart_id, float> bp_exposure;
786 // May need to iterate over all body parts several times, so make a copy
787 const std::vector<bodypart_id> all_body_parts = get_all_body_parts();
788
789 // Initially, all parts are assumed to be fully exposed
790 for( const bodypart_id &bp : all_body_parts ) {
791 bp_exposure[bp] = 1.0;
792 }
793 // For every item worn, for every body part, adjust coverage
794 for( const item &it : worn ) {
795 // What body parts does this item cover?
796 body_part_set covered = it.get_covered_body_parts();
797 for( const bodypart_id &bp : all_body_parts ) {
798 if( bp->token != num_bp && !covered.test( bp->token ) ) {
799 continue;
800 }
801 // How much exposure does this item leave on this part? (1.0 == naked)
802 float part_exposure = 1.0 - it.get_coverage() / 100.0f;
803 // Coverage multiplies, so two layers with 50% coverage will together give 75%
804 bp_exposure[bp] = bp_exposure[bp] * part_exposure;
805 }
806 }
807 return bp_exposure;
808}
@ num_bp
Definition: bodypart.h:52
std::vector< bodypart_id > get_all_body_parts(bool only_main=false) const
Returns body parts this creature have.
Definition: creature.cpp:1633
bool test(const body_part &bp) const
Definition: bodypart.h:237

References all_body_parts, Creature::get_all_body_parts(), num_bp, body_part_set::test(), and worn.

Referenced by suffer_from_sunburn().

◆ bodytemp_color()

nc_color Character::bodytemp_color ( int  bp) const

Define color for displaying the body temperature.

Definition at line 10416 of file character.cpp.

10417{
10418 nc_color color = c_light_gray; // default
10419 if( bp == bp_eyes ) {
10420 color = c_light_gray; // Eyes don't count towards warmth
10421 } else if( temp_conv[bp] > BODYTEMP_SCORCHING ) {
10422 color = c_red;
10423 } else if( temp_conv[bp] > BODYTEMP_VERY_HOT ) {
10425 } else if( temp_conv[bp] > BODYTEMP_HOT ) {
10426 color = c_yellow;
10427 } else if( temp_conv[bp] > BODYTEMP_COLD ) {
10428 color = c_green;
10429 } else if( temp_conv[bp] > BODYTEMP_VERY_COLD ) {
10431 } else if( temp_conv[bp] > BODYTEMP_FREEZING ) {
10432 color = c_cyan;
10433 } else if( temp_conv[bp] <= BODYTEMP_FREEZING ) {
10434 color = c_blue;
10435 }
10436 return color;
10437}
#define c_cyan
Definition: color.h:24
#define c_light_red
Definition: color.h:27
static nc_color color(const T_t &t)
static constexpr int BODYTEMP_SCORCHING
Definition: weather.h:42
static constexpr int BODYTEMP_VERY_HOT
Level 3 hotness.
Definition: weather.h:40
static constexpr int BODYTEMP_VERY_COLD
Frostbite timer will not improve while below this point.
Definition: weather.h:32
static constexpr int BODYTEMP_FREEZING
This value means frostbite occurs at the warmest temperature of 1C. If changed, the temp_conv calcula...
Definition: weather.h:30

References BODYTEMP_COLD, BODYTEMP_FREEZING, BODYTEMP_HOT, BODYTEMP_SCORCHING, BODYTEMP_VERY_COLD, BODYTEMP_VERY_HOT, bp_eyes, c_blue, c_cyan, c_green, c_light_blue, c_light_gray, c_light_red, c_red, c_yellow, color(), and temp_conv.

Referenced by character_display::print_encumbrance().

◆ bodytemp_modifier_traits()

int Character::bodytemp_modifier_traits ( bool  overheated) const

Correction factor of the body temperature due to traits and mutations.

Definition at line 9497 of file character.cpp.

9498{
9499 int mod = 0;
9500 for( const trait_id &iter : get_mutations() ) {
9501 mod += overheated ? iter->bodytemp_min : iter->bodytemp_max;
9502 }
9503 return mod;
9504}
std::vector< trait_id > get_mutations(bool include_hidden=true) const
Get the idents of all traits/mutations.

References get_mutations().

Referenced by update_bodytemp().

◆ bodytemp_modifier_traits_floor()

int Character::bodytemp_modifier_traits_floor ( ) const

Correction factor of the body temperature due to traits and mutations for player lying on the floor.

Definition at line 9506 of file character.cpp.

9507{
9508 int mod = 0;
9509 for( const trait_id &iter : get_mutations() ) {
9510 mod += iter->bodytemp_sleep;
9511 }
9512 return mod;
9513}

References get_mutations().

Referenced by floor_warmth().

◆ bodyweight()

units::mass Character::bodyweight ( ) const

Definition at line 6718 of file character.cpp.

6719{
6720 return units::from_kilogram( bmi() * std::pow( height() / 100.0f, 2 ) );
6721}
int height() const
Definition: character.cpp:6799
float bmi() const
Definition: character.cpp:6713
constexpr quantity< value_type, mass_in_milligram_tag > from_kilogram(const value_type v)
Definition: units_mass.h:47

References bmi(), units::from_kilogram(), and height().

Referenced by get_weight(), and get_weight_string().

◆ bonus_damage()

float Character::bonus_damage ( bool  random) const

Returns the bonus bashing damage the player deals based on their stats.

Strength increases bashing damage

Definition at line 862 of file melee.cpp.

863{
864 /** @EFFECT_STR increases bashing damage */
865 if( random ) {
866 return rng_float( get_str() / 2.0f, get_str() );
867 }
868
869 return get_str() * 0.75f;
870}
virtual int get_str() const
Getters for stats exclusive to characters.
Definition: character.cpp:4052
type random()
Returns a random direction.
Definition: overmap.cpp:4218
double rng_float(double lo, double hi)
Definition: rng.cpp:28

References get_str(), om_direction::random(), and rng_float().

Referenced by draw_stats_info(), roll_bash_damage(), and set_stats().

◆ bonus_from_enchantments()

double Character::bonus_from_enchantments ( double  base,
enchant_vals::mod  value,
bool  round = false 
) const

Calculate bonus from enchantments for given base value.

Definition at line 7865 of file character.cpp.

7867{
7868 return enchantment_cache->calc_bonus( value, base, round );
7869}
pimpl< enchantment > enchantment_cache
Definition: character.h:2251

References enchantment_cache.

Referenced by armor_enchantment_adjust(), attack_cost(), calc_needs_rates(), get_stamina_max(), known_magic::mana_regen_rate(), known_magic::max_mana(), metabolic_rate_base(), run_cost(), and update_stamina().

◆ bp_to_hp()

hp_part Character::bp_to_hp ( body_part  bp)
static

Converts a body_part to an hp_part.

Definition at line 6417 of file character.cpp.

6418{
6419 switch( bp ) {
6420 case bp_head:
6421 case bp_eyes:
6422 case bp_mouth:
6423 return hp_head;
6424 case bp_torso:
6425 return hp_torso;
6426 case bp_arm_l:
6427 case bp_hand_l:
6428 return hp_arm_l;
6429 case bp_arm_r:
6430 case bp_hand_r:
6431 return hp_arm_r;
6432 case bp_leg_l:
6433 case bp_foot_l:
6434 return hp_leg_l;
6435 case bp_leg_r:
6436 case bp_foot_r:
6437 return hp_leg_r;
6438 default:
6439 return num_hp_parts;
6440 }
6441}

References bp_arm_l, bp_arm_r, bp_eyes, bp_foot_l, bp_foot_r, bp_hand_l, bp_hand_r, bp_head, bp_leg_l, bp_leg_r, bp_mouth, bp_torso, hp_arm_l, hp_arm_r, hp_head, hp_leg_l, hp_leg_r, hp_torso, and num_hp_parts.

Referenced by iexamine::autodoc(), explosion_handler::shrapnel(), and heal_actor::use_healing_item().

◆ build_mut_dependency_map()

void Character::build_mut_dependency_map ( const trait_id mut,
std::unordered_map< trait_id, int > &  dependency_map,
int  distance 
)

Recursively traverses the mutation's prerequisites and replacements, building up a map.

Definition at line 7728 of file character.cpp.

7730{
7731 // Skip base traits and traits we've seen with a lower distance
7732 const auto lowest_distance = dependency_map.find( mut );
7733 if( !has_base_trait( mut ) && ( lowest_distance == dependency_map.end() ||
7734 distance < lowest_distance->second ) ) {
7735 dependency_map[mut] = distance;
7736 // Recurse over all prerequisite and replacement mutations
7737 const mutation_branch &mdata = mut.obj();
7738 for( const trait_id &i : mdata.prereqs ) {
7739 build_mut_dependency_map( i, dependency_map, distance + 1 );
7740 }
7741 for( const trait_id &i : mdata.prereqs2 ) {
7742 build_mut_dependency_map( i, dependency_map, distance + 1 );
7743 }
7744 for( const trait_id &i : mdata.replacements ) {
7745 build_mut_dependency_map( i, dependency_map, distance + 1 );
7746 }
7747 }
7748}
void build_mut_dependency_map(const trait_id &mut, std::unordered_map< trait_id, int > &dependency_map, int distance)
Recursively traverses the mutation's prerequisites and replacements, building up a map.
Definition: character.cpp:7728
bool has_base_trait(const trait_id &b) const
Returns true if the player has the entered starting trait.
Definition: mutation.cpp:121
const T & obj() const
Returns the actual object this id refers to.
Definition: achievement.cpp:58
std::vector< trait_id > replacements
Definition: mutation.h:263
std::vector< trait_id > prereqs
Definition: mutation.h:258
std::vector< trait_id > prereqs2
Definition: mutation.h:259

References build_mut_dependency_map(), has_base_trait(), string_id< T >::obj(), mutation_branch::prereqs, mutation_branch::prereqs2, mutation_branch::replacements, and second.

Referenced by build_mut_dependency_map(), and set_highest_cat_level().

◆ burn_fuel()

bool Character::burn_fuel ( bionic bio,
bool  start = false 
)

Convert fuel to bionic power.

Definition at line 1153 of file bionics.cpp.

1154{
1155 if( ( bio.info().fuel_opts.empty() && !bio.info().is_remote_fueled ) ||
1157 return true;
1158 }
1159 const bool is_metabolism_powered = bio.is_this_fuel_powered( fuel_type_metabolism );
1160 const bool is_cable_powered = bio.info().is_remote_fueled;
1161 std::vector<itype_id> fuel_available = get_fuel_available( bio.id );
1162 float effective_efficiency = get_effective_efficiency( bio, bio.info().fuel_efficiency );
1163
1164 if( is_cable_powered ) {
1165 const itype_id remote_fuel = find_remote_fuel();
1166 if( !remote_fuel.is_empty() ) {
1167 fuel_available.emplace_back( remote_fuel );
1168 if( remote_fuel == fuel_type_sun_light ) {
1169 const item *pack = item_worn_with_flag( "SOLARPACK_ON" );
1170 effective_efficiency = pack != nullptr ? pack->type->solar_efficiency : 0;
1171 }
1172 // TODO: check for available fuel in remote source
1173 } else if( !start ) {
1175 _( "Your %s runs out of fuel and turn off." ),
1176 _( "<npcname>'s %s runs out of fuel and turn off." ),
1177 bio.info().name );
1178 bio.powered = false;
1179 deactivate_bionic( bio, true );
1180 return false;
1181 }
1182 }
1183
1184 if( start && fuel_available.empty() ) {
1185 add_msg_player_or_npc( m_bad, _( "Your %s does not have enough fuel to start." ),
1186 _( "<npcname>'s %s does not have enough fuel to start." ),
1187 bio.info().name );
1188 deactivate_bionic( bio );
1189 return false;
1190 }
1191 // don't produce power on start to avoid instant recharge exploit by turning bionic ON/OFF
1192 //in the menu
1193 if( !start ) {
1194 for( const itype_id &fuel : fuel_available ) {
1195 const item &tmp_fuel = item( fuel );
1196 const int fuel_energy = tmp_fuel.fuel_energy();
1197 const bool is_perpetual_fuel = tmp_fuel.has_flag( flag_PERPETUAL );
1198
1199 int current_fuel_stock;
1200 if( is_metabolism_powered ) {
1201 current_fuel_stock = std::max( 0.0f, get_stored_kcal() - 0.8f *
1202 max_stored_kcal() );
1203 } else if( is_perpetual_fuel ) {
1204 current_fuel_stock = 1;
1205 } else if( is_cable_powered ) {
1206 current_fuel_stock = std::stoi( get_value( "rem_" + fuel.str() ) );
1207 } else {
1208 current_fuel_stock = std::stoi( get_value( fuel.str() ) );
1209 }
1210
1211 if( !bio.has_flag( flag_SAFE_FUEL_OFF ) &&
1212 get_power_level() + units::from_kilojoule( fuel_energy ) * effective_efficiency
1213 > get_max_power_level() ) {
1214 if( !bio.is_auto_start_keep_full() ) {
1215 if( is_metabolism_powered ) {
1216 add_msg_player_or_npc( m_info, _( "Your %s turns off to not waste calories." ),
1217 _( "<npcname>'s %s turns off to not waste calories." ),
1218 bio.info().name );
1219 } else if( is_perpetual_fuel ) {
1220 add_msg_player_or_npc( m_info, _( "Your %s turns off after filling your power banks." ),
1221 _( "<npcname>'s %s turns off after filling their power banks." ),
1222 bio.info().name );
1223 } else {
1224 add_msg_player_or_npc( m_info, _( "Your %s turns off to not waste fuel." ),
1225 _( "<npcname>'s %s turns off to not waste fuel." ),
1226 bio.info().name );
1227 }
1228 }
1229 bio.powered = false;
1230 deactivate_bionic( bio, true );
1231 return false;
1232 } else {
1233 if( current_fuel_stock > 0 ) {
1234 map &here = get_map();
1235 if( is_metabolism_powered ) {
1236 const int kcal_consumed = fuel_energy;
1237 // 1kcal = 4187 J
1238 const units::energy power_gain = kcal_consumed * 4184_J * effective_efficiency;
1239 mod_stored_kcal( -kcal_consumed );
1240 mod_power_level( power_gain );
1241 } else if( is_perpetual_fuel ) {
1242 if( fuel == fuel_type_sun_light && g->is_in_sunlight( pos() ) ) {
1243 const weather_type_id &wtype = current_weather( pos() );
1244 const float tick_sunlight = incident_sunlight( wtype, calendar::turn );
1245 const double intensity = tick_sunlight / default_daylight_level();
1246 mod_power_level( units::from_kilojoule( fuel_energy ) * intensity * effective_efficiency );
1247 } else if( fuel == fuel_type_wind ) {
1248 int vehwindspeed = 0;
1249 const optional_vpart_position vp = here.veh_at( pos() );
1250 if( vp ) {
1251 // vehicle velocity in mph
1252 vehwindspeed = std::abs( vp->vehicle().velocity / 100 );
1253 }
1254 const weather_manager &wm = get_weather();
1255 const double windpower = get_local_windpower( wm.windspeed + vehwindspeed,
1257 g->is_sheltered( pos() ) );
1258 mod_power_level( units::from_kilojoule( fuel_energy ) * windpower * effective_efficiency );
1259 } else {
1260 mod_power_level( units::from_kilojoule( fuel_energy ) * effective_efficiency );
1261 }
1262 } else if( is_cable_powered ) {
1263 int to_consume = 1;
1265 to_consume = 0;
1266 }
1267 const int unconsumed = consume_remote_fuel( to_consume );
1268 if( unconsumed == 0 && to_consume == 1 ) {
1269 mod_power_level( units::from_kilojoule( fuel_energy ) * effective_efficiency );
1270 current_fuel_stock -= 1;
1271 } else if( to_consume == 1 ) {
1272 current_fuel_stock = 0;
1273 }
1274 set_value( "rem_" + fuel.str(), std::to_string( current_fuel_stock ) );
1275 } else {
1276 current_fuel_stock -= 1;
1277 set_value( fuel.str(), std::to_string( current_fuel_stock ) );
1278 update_fuel_storage( fuel );
1279 mod_power_level( units::from_kilojoule( fuel_energy ) * effective_efficiency );
1280 }
1281
1282 heat_emission( bio, fuel_energy );
1283 if( bio.info().power_gen_emission ) {
1284 here.emit_field( pos(), bio.info().power_gen_emission );
1285 }
1286 } else {
1287
1288 if( is_metabolism_powered ) {
1290 _( "Stored calories are below the safe threshold, your %s shuts down to preserve your health." ),
1291 _( "Stored calories are below the safe threshold, <npcname>'s %s shuts down to preserve their health." ),
1292 bio.info().name );
1293 } else {
1294 remove_value( fuel.str() );
1296 _( "Your %s runs out of fuel and turn off." ),
1297 _( "<npcname>'s %s runs out of fuel and turn off." ),
1298 bio.info().name );
1299 }
1300
1301 bio.powered = false;
1302 deactivate_bionic( bio, true );
1303 return false;
1304 }
1305 }
1306 }
1307 }
1308 return true;
1309}
static const std::string flag_SAFE_FUEL_OFF("SAFE_FUEL_OFF")
static const std::string flag_PERPETUAL("PERPETUAL")
static const itype_id fuel_type_wind("wind")
static const itype_id fuel_type_metabolism("metabolism")
static const itype_id fuel_type_muscle("muscle")
static const itype_id fuel_type_sun_light("sunlight")
double default_daylight_level()
How much light is provided in full daylight.
Definition: calendar.cpp:62
std::string to_string(const time_duration &d)
Returns a string showing a duration.
Definition: calendar.cpp:327
std::vector< itype_id > get_fuel_available(const bionic_id &bio) const
Return list of available fuel for this bionic.
Definition: character.cpp:1994
const item * item_worn_with_flag(const std::string &flag, const bodypart_id &bp=bodypart_str_id::NULL_ID()) const
Returns the first worn item with a given flag.
Definition: character.cpp:3239
virtual void mod_stored_kcal(int nkcal)
Modifiers for need values exclusive to characters.
Definition: character.cpp:4287
void heat_emission(bionic &bio, int fuel_energy)
Handle heat from exothermic power generation.
Definition: bionics.cpp:1452
float get_effective_efficiency(bionic &bio, float fuel_efficiency)
Applies modifier to fuel_efficiency and returns the resulting efficiency.
Definition: bionics.cpp:1472
int get_stored_kcal() const
Getter for need values exclusive to characters.
Definition: character.cpp:4282
int consume_remote_fuel(int amount)
Consume fuel used by remote powered bionic, return amount of request unfulfilled (0 if totally succes...
Definition: bionics.cpp:1409
void update_fuel_storage(const itype_id &fuel)
Updates which bionic contain fuel and which is empty.
Definition: character.cpp:2040
itype_id find_remote_fuel(bool look_only=false)
Find fuel used by remote powered bionic.
Definition: bionics.cpp:1355
void set_value(const std::string &key, const std::string &value)
Definition: creature.cpp:1337
float fuel_energy() const
Returns energy of one charge of this item as fuel for an engine.
Definition: item.cpp:6821
const itype * type
Definition: item.h:2157
void emit_field(const tripoint &pos, const emit_id &src, float mul=1.0f)
Runs one cycle of emission src which may result in propagation of fields.
Definition: map_field.cpp:1928
int winddirection
Definition: weather.h:194
const weather_type_id & current_weather(const tripoint &location, const time_point &t)
Definition: weather.cpp:143
int incident_sunlight(const weather_type_id &wtype, const time_point &t)
Amount of sunlight incident at the ground, taking weather and time of day into account.
Definition: weather.cpp:107
emit_id power_gen_emission
Type of field emitted by this bionic when it produces energy.
Definition: bionics.h:77
std::vector< itype_id > fuel_opts
Fuel types that can be used by this bionic.
Definition: bionics.h:65
float fuel_efficiency
Fraction of fuel energy converted to bionic power.
Definition: bionics.h:69
bool has_flag(const std::string &flag) const
Definition: bionics.cpp:2663
bool is_this_fuel_powered(const itype_id &this_fuel) const
Definition: bionics.cpp:2678
float solar_efficiency
Efficiency of solar energy conversion for solarpacks.
Definition: itype.h:1035

References _, Creature::add_msg_player_or_npc(), consume_remote_fuel(), current_weather(), deactivate_bionic(), default_daylight_level(), map::emit_field(), find_remote_fuel(), flag_PERPETUAL(), flag_SAFE_FUEL_OFF(), units::from_kilojoule(), bionic_data::fuel_efficiency, item::fuel_energy(), bionic_data::fuel_opts, fuel_type_metabolism, fuel_type_muscle, fuel_type_sun_light, fuel_type_wind, g, get_effective_efficiency(), get_fuel_available(), get_local_windpower(), get_map(), get_max_power_level(), get_power_level(), get_stored_kcal(), Creature::get_value(), get_weather(), global_omt_location(), bionic::has_flag(), item::has_flag(), heat_emission(), bionic::id, incident_sunlight(), bionic::info(), bionic::is_auto_start_keep_full(), string_id< T >::is_empty(), bionic_data::is_remote_fueled, bionic::is_this_fuel_powered(), item_worn_with_flag(), m_bad, m_info, max_stored_kcal(), mod_power_level(), mod_stored_kcal(), bionic_data::name, overmap_buffer, pos(), bionic_data::power_gen_emission, bionic::powered, Creature::remove_value(), Creature::set_value(), itype::solar_efficiency, overmapbuffer::ter(), to_string(), calendar::turn, item::type, update_fuel_storage(), map::veh_at(), weather_manager::winddirection, and weather_manager::windspeed.

Referenced by activate_bionic(), and process_bionic().

◆ burn_move_stamina()

void Character::burn_move_stamina ( int  moves)

Definition at line 7079 of file character.cpp.

7080{
7081 int overburden_percentage = 0;
7082 units::mass current_weight = weight_carried();
7083 // Make it at least 1 gram to avoid divide-by-zero warning
7084 units::mass max_weight = std::max( weight_capacity(), 1_gram );
7085 if( current_weight > max_weight ) {
7086 overburden_percentage = ( current_weight - max_weight ) * 100 / max_weight;
7087 }
7088
7089 int burn_ratio = get_option<int>( "PLAYER_BASE_STAMINA_BURN_RATE" );
7090 for( const bionic_id &bid : get_bionic_fueled_with( item( "muscle" ) ) ) {
7091 if( has_active_bionic( bid ) ) {
7092 burn_ratio = burn_ratio * 2 - 3;
7093 }
7094 }
7095 burn_ratio += overburden_percentage;
7096 if( move_mode == CMM_RUN ) {
7097 burn_ratio = burn_ratio * 7;
7098 }
7099 mod_stamina( -( ( moves * burn_ratio ) / 100.0 ) * stamina_move_cost_modifier() );
7100 add_msg( m_debug, "Stamina burn: %d", -( ( moves * burn_ratio ) / 100 ) );
7101 // Chance to suffer pain if overburden and stamina runs out or has trait BADBACK
7102 // Starts at 1 in 25, goes down by 5 for every 50% more carried
7103 if( ( current_weight > max_weight ) && ( has_trait( trait_BADBACK ) || get_stamina() == 0 ) &&
7104 one_in( 35 - 5 * current_weight / ( max_weight / 2 ) ) ) {
7105 add_msg_if_player( m_bad, _( "Your body strains under the weight!" ) );
7106 // 1 more pain for every 800 grams more (5 per extra STR needed)
7107 if( ( ( current_weight - max_weight ) / 800_gram > get_pain() && get_pain() < 100 ) ) {
7108 mod_pain( 1 );
7109 }
7110 }
7111}
static const trait_id trait_BADBACK("BADBACK")
std::vector< bionic_id > get_bionic_fueled_with(const item &it) const
Return bionic_id of bionics able to use it as fuel.
Definition: character.cpp:1846
units::mass weight_carried() const
Definition: character.cpp:2507
void mod_stamina(int mod)
Definition: character.cpp:7069
float stamina_move_cost_modifier() const
Definition: character.cpp:7113
virtual int get_pain() const
Definition: creature.cpp:1372

References _, add_msg(), Creature::add_msg_if_player(), CMM_RUN, get_bionic_fueled_with(), Creature::get_pain(), get_stamina(), has_active_bionic(), has_trait(), m_bad, m_debug, mod_pain(), mod_stamina(), move_mode, Creature::moves, one_in(), stamina_move_cost_modifier(), trait_BADBACK, weight_capacity(), and weight_carried().

Referenced by avatar_action::swim(), and game::walk_move().

◆ calc_all_parts_hp()

void Character::calc_all_parts_hp ( float  hp_mod = 0.0,
float  hp_adjust = 0.0,
int  str_max = 0 
)

Sets hp for all body parts.

Definition at line 1580 of file character.cpp.

1581{
1582 for( const std::pair<const bodypart_str_id, bodypart> &part : get_body() ) {
1583 bodypart &bp = *get_part( part.first );
1584 int new_max = ( part.first->base_hp + str_max * 3 + hp_adjustment ) * hp_mod;
1585
1586 if( has_trait( trait_id( "GLASSJAW" ) ) && part.first == bodypart_str_id( "head" ) ) {
1587 new_max *= 0.8;
1588 }
1589
1590 float max_hp_ratio = static_cast<float>( new_max ) /
1591 static_cast<float>( bp.get_hp_max() );
1592
1593 int new_cur = std::ceil( static_cast<float>( bp.get_hp_cur() ) * max_hp_ratio );
1594
1595 bp.set_hp_max( std::max( new_max, 1 ) );
1596 bp.set_hp_cur( std::max( std::min( new_cur, new_max ), 0 ) );
1597 }
1598}
string_id< body_part_type > bodypart_str_id
Definition: bodypart.h:22
const std::map< bodypart_str_id, bodypart > & get_body() const
Definition: creature.cpp:1533
bodypart * get_part(const bodypart_id &id)
Definition: creature.cpp:1546
int get_hp_max() const
Definition: bodypart.cpp:400
int get_hp_cur() const
Definition: bodypart.cpp:395
void set_hp_max(int set)
Definition: bodypart.cpp:425
void set_hp_cur(int set)
Definition: bodypart.cpp:420

References Creature::get_body(), bodypart::get_hp_cur(), bodypart::get_hp_max(), Creature::get_part(), has_trait(), bodypart::set_hp_cur(), bodypart::set_hp_max(), str_max, and trait_id.

Referenced by recalc_hp().

◆ calc_encumbrance() [1/2]

char_encumbrance_data Character::calc_encumbrance ( ) const
protected

Recalculate encumbrance for all body parts.

Definition at line 3636 of file character.cpp.

3637{
3638 return calc_encumbrance( item() );
3639}
char_encumbrance_data calc_encumbrance() const
Recalculate encumbrance for all body parts.
Definition: character.cpp:3636

References calc_encumbrance().

Referenced by calc_encumbrance(), get_encumbrance(), on_item_takeoff(), on_item_wear(), and reset_encumbrance().

◆ calc_encumbrance() [2/2]

char_encumbrance_data Character::calc_encumbrance ( const item new_item) const
protected

Recalculate encumbrance for all body parts as if new_item was also worn.

Definition at line 3641 of file character.cpp.

3642{
3643
3645
3646 item_encumb( enc, new_item );
3647 mut_cbm_encumb( enc );
3648
3649 return enc;
3650}
void item_encumb(char_encumbrance_data &vals, const item &new_item) const
Applies encumbrance from items only If new_item is not null, then calculate under the asumption that ...
Definition: character.cpp:3946
void mut_cbm_encumb(char_encumbrance_data &vals) const
Applies encumbrance from mutations and bionics only.
Definition: character.cpp:4009

References item_encumb(), and mut_cbm_encumb().

◆ calc_needs_rates()

needs_rates Character::calc_needs_rates ( ) const

Definition at line 4882 of file character.cpp.

4883{
4884 const effect &sleep = get_effect( effect_sleep );
4885 const bool has_recycler = has_bionic( bio_recycler );
4886 const bool asleep = !sleep.is_null();
4887
4888 needs_rates rates;
4889 rates.hunger = metabolic_rate();
4890
4891 add_msg_if_player( m_debug, "Metabolic rate: %.2f", rates.hunger );
4892
4893 static const std::string player_thirst_rate( "PLAYER_THIRST_RATE" );
4894 rates.thirst = get_option< float >( player_thirst_rate );
4895 static const std::string thirst_modifier( "thirst_modifier" );
4896 rates.thirst *= 1.0f + mutation_value( thirst_modifier ) +
4898 static const std::string slows_thirst( "SLOWS_THIRST" );
4899 if( worn_with_flag( slows_thirst ) ) {
4900 rates.thirst *= 0.7f;
4901 }
4902
4903 static const std::string player_fatigue_rate( "PLAYER_FATIGUE_RATE" );
4904 rates.fatigue = get_option< float >( player_fatigue_rate );
4905 static const std::string fatigue_modifier( "fatigue_modifier" );
4906 rates.fatigue *= 1.0f + mutation_value( fatigue_modifier ) +
4908
4909 // Note: intentionally not in metabolic rate
4910 if( has_recycler ) {
4911 // Recycler won't help much with mutant metabolism - it is intended for human one
4912 rates.hunger = std::min( rates.hunger, std::max( 0.5f, rates.hunger - 0.5f ) );
4913 rates.thirst = std::min( rates.thirst, std::max( 0.5f, rates.thirst - 0.5f ) );
4914 }
4915
4916 if( asleep ) {
4917 static const std::string fatigue_regen_modifier( "fatigue_regen_modifier" );
4918 // Multiplied by 2 to account for legacy (bugged to always apply)
4919 // bonus for sleeping over 2 hours
4920 rates.recovery = 2.0f * ( 1.0f + mutation_value( fatigue_regen_modifier ) );
4921 if( is_hibernating() ) {
4922 // Hunger and thirst advance *much* more slowly whilst we hibernate.
4923 rates.hunger *= ( 1.0f / 7.0f );
4924 rates.thirst *= ( 1.0f / 7.0f );
4925 }
4926 rates.recovery -= static_cast<float>( get_perceived_pain() ) / 60;
4927
4928 } else {
4929 rates.recovery = 0;
4930 }
4931
4933 // Much of the body's needs are taken care of by the trees.
4934 // Hair Roots don't provide any bodily needs.
4936 rates.hunger *= 0.5f;
4937 rates.thirst *= 0.5f;
4938 rates.fatigue *= 0.5f;
4939 }
4940 }
4941
4943 // Transpiration, the act of moving nutrients with evaporating water, can take a very heavy toll on your thirst when it's really hot.
4944 rates.thirst *= ( ( get_weather().get_temperature( pos() ) - 32.5f ) / 40.0f );
4945 }
4946
4947 if( is_npc() ) {
4948 rates.hunger *= 0.25f;
4949 rates.thirst *= 0.25f;
4950 }
4951
4952 rates.thirst = std::max( rates.thirst, 0.0f );
4953 rates.hunger = std::max( rates.hunger, 0.0f );
4954 rates.fatigue = std::max( rates.fatigue, 0.0f );
4955 rates.recovery = std::max( rates.recovery, 0.0f );
4956
4957 return rates;
4958}
static const activity_id ACT_TREE_COMMUNION("ACT_TREE_COMMUNION")
static const trait_id trait_ROOTS2("ROOTS2")
static const bionic_id bio_recycler("bio_recycler")
static const efftype_id effect_sleep("sleep")
static const trait_id trait_TRANSPIRATION("TRANSPIRATION")
static const trait_id trait_ROOTS3("ROOTS3")
float metabolic_rate() const
Current metabolic rate due to traits, hunger, speed, etc.
bool is_hibernating() const
Returns if the player has hibernation mutation and is asleep and well fed.
Definition: character.cpp:5139
bool has_activity(const activity_id &type) const
Check if player currently has a given activity.
Definition: character.cpp:9178
int get_perceived_pain() const override
Returns perceived pain (reduced with painkillers)
Definition: character.cpp:789
int get_temperature(const tripoint &location) const
Definition: weather.cpp:1107
@ sleep
Will recharge only when character is asleep.
float hunger
Definition: character.h:195
float recovery
Definition: character.h:197
float fatigue
Definition: character.h:196
float thirst
Definition: character.h:194

References ACT_TREE_COMMUNION, Creature::add_msg_if_player(), bio_recycler, bonus_from_enchantments(), effect_sleep, needs_rates::fatigue, enchant_vals::FATIGUE, Creature::get_effect(), get_perceived_pain(), weather_manager::get_temperature(), get_weather(), has_activity(), has_bionic(), has_trait(), needs_rates::hunger, is_hibernating(), Creature::is_npc(), m_debug, metabolic_rate(), mutation_value(), pos(), needs_rates::recovery, sleep, needs_rates::thirst, enchant_vals::THIRST, trait_ROOTS2, trait_ROOTS3, trait_TRANSPIRATION, and worn_with_flag().

Referenced by update_needs(), and update_stomach().

◆ can_consume()

bool Character::can_consume ( const item it) const

Check character's capability of consumption overall.

Definition at line 1499 of file consumption.cpp.

1500{
1501 if( can_consume_as_is( it ) ) {
1502 return true;
1503 }
1504 // Checking NO_RELOAD to prevent consumption of `battery` when contained in `battery_car` (#20012)
1505 return !it.is_container_empty() && !it.has_flag( flag_NO_RELOAD ) &&
1507}
bool can_consume_as_is(const item &it) const
Check whether character can consume this very item.
item & front()
this is an artifact of the previous code using front() everywhere for contents.
bool is_container_empty() const
Whether this item has no contents at all.
Definition: item.cpp:6842
static const std::string flag_NO_RELOAD("NO_RELOAD")

References can_consume_as_is(), item::contents, flag_NO_RELOAD(), item_contents::front(), item::has_flag(), and item::is_container_empty().

Referenced by find_auto_consume(), and examine_item_menu::rate_action_eat().

◆ can_consume_as_is()

bool Character::can_consume_as_is ( const item it) const

Check whether character can consume this very item.

Definition at line 1489 of file consumption.cpp.

1490{
1491 return it.is_comestible() || can_consume_for_bionic( it );
1492}
bool can_consume_for_bionic(const item &it) const
bool is_comestible() const
Definition: item.cpp:6592

References can_consume_for_bionic(), and item::is_comestible().

Referenced by can_consume(), consume(), avatar_action::eat(), and get_consumable_from().

◆ can_consume_for_bionic()

bool Character::can_consume_for_bionic ( const item it) const

Definition at line 1494 of file consumption.cpp.

1495{
1497}
rechargeable_cbm get_cbm_rechargeable_with(const item &it) const

References get_cbm_rechargeable_with(), and none.

Referenced by can_consume_as_is().

◆ can_eat()

ret_val< edible_rating > Character::can_eat ( const item food) const

Can the food be [theoretically] eaten no matter the consequen ces?

Definition at line 642 of file consumption.cpp.

643{
644
645 const auto &comest = food.get_comestible();
646 if( !comest ) {
647 return ret_val<edible_rating>::make_failure( _( "That doesn't look edible." ) );
648 }
649
650 if( food.has_flag( flag_INEDIBLE ) ) {
651 if( ( food.has_flag( flag_CATTLE ) && !has_trait( trait_THRESH_CATTLE ) ) ||
654 ( food.has_flag( flag_BIRD ) && !has_trait( trait_THRESH_BIRD ) ) ) {
655 return ret_val<edible_rating>::make_failure( _( "That doesn't look edible to you." ) );
656 }
657 }
658
659 if( food.is_craft() ) {
660 return ret_val<edible_rating>::make_failure( _( "That doesn't look edible in its current form." ) );
661 }
662
663 if( food.has_own_flag( "DIRTY" ) ) {
665 _( "This is full of dirt after being on the ground." ) );
666 }
667
668 const bool eat_verb = food.has_flag( flag_USE_EAT_VERB );
669 const bool edible = eat_verb || comest->comesttype == comesttype_FOOD;
670 const bool drinkable = !eat_verb && comest->comesttype == comesttype_DRINK;
671
672 // TODO: This condition occurs way too often. Unify it.
673 // update Sep. 26 2018: this apparently still occurs way too often. yay!
675 return ret_val<edible_rating>::make_failure( _( "You can't do that while underwater." ) );
676 }
677
678 if( edible || drinkable ) {
679 for( const auto &elem : food.type->materials ) {
680 if( !elem->edible() ) {
681 return ret_val<edible_rating>::make_failure( _( "That doesn't look edible in its current form." ) );
682 }
683 }
684 }
685
686 if( !comest->tool.is_null() ) {
687 const bool has = item::count_by_charges( comest->tool )
688 ? has_charges( comest->tool, 1 )
689 : has_amount( comest->tool, 1 );
690 if( !has ) {
692 string_format( _( "You need a %s to consume that!" ),
693 item::nname( comest->tool ) ) );
694 }
695 }
696
697 // For all those folks who loved eating marloss berries. D:< mwuhahaha
699 !food.has_flag( flag_NO_INGEST ) ) {
701 _( "We can't eat that. It's not right for us." ) );
702 }
703 // Here's why PROBOSCIS is such a negative trait.
704 if( has_trait( trait_PROBOSCIS ) && !( drinkable || food.is_medication() ) ) {
706 _( "Ugh, you can't drink that!" ) );
707 }
708 if( has_trait( trait_CARNIVORE ) && ( compute_effective_nutrients( food ).kcal ) > 0 &&
711 _( "Eww. Inedible plant stuff!" ) );
712 }
713
716 // Like non-cannibal, but more strict!
718 _( "The thought of eating that makes you feel sick." ) );
719 }
720
721 for( const trait_id &mut : get_mutations() ) {
722 if( !food.made_of_any( mut.obj().can_only_eat ) && !mut.obj().can_only_eat.empty() &&
723 !food.has_flag( flag_NO_INGEST ) ) {
725 _( "You can't eat this." ) );
726 }
727 }
728
730}
nutrients compute_effective_nutrients(const item &) const
bool has_charges(const itype_id &it, int quantity, const std::function< bool(const item &)> &filter=return_true< item >) const
Definition: character.cpp:9554
bool count_by_charges() const
Definition: item.cpp:6010
const cata::value_ptr< islot_comestible > & get_comestible() const
Definition: item.cpp:10124
static std::string nname(const itype_id &id, unsigned int quantity=1)
Returns the translated item name for the item with given id.
Definition: item.cpp:9922
bool is_craft() const
Definition: item.cpp:6923
bool made_of_any(const std::set< material_id > &mat_idents) const
Check we are made of at least one of a set (e.g.
Definition: item.cpp:6440
bool is_medication() const
Definition: item.cpp:6603
bool has_any_flag(const Container &flags) const
Definition: item.h:1401
bool has_own_flag(const std::string &flag) const
Checks whether item itself has given flag (doesn't check item type or gunmods).
Definition: item.cpp:5303
static ret_val make_success(T val=default_success::value)
Definition: ret_val.h:42
static ret_val make_failure(T val=default_failure::value)
Definition: ret_val.h:46
bool has_amount(const itype_id &what, int qty, bool pseudo=true, const std::function< bool(const item &)> &filter=return_true< item >) const
Check instance provides at least qty of an item (.
Definition: visitable.cpp:1108
static const trait_id trait_RUMINANT("RUMINANT")
const std::vector< std::string > carnivore_blacklist
static const std::string flag_INEDIBLE("INEDIBLE")
static const trait_id trait_HERBIVORE("HERBIVORE")
static const trait_id trait_CARNIVORE("CARNIVORE")
static const std::string comesttype_DRINK("DRINK")
static const trait_id trait_THRESH_BIRD("THRESH_BIRD")
const std::vector< std::string > herbivore_blacklist(temparray.begin(), temparray.end())
static const std::string flag_BIRD("BIRD")
static const trait_id trait_PROBOSCIS("PROBOSCIS")
static const std::string flag_USE_EAT_VERB("USE_EAT_VERB")
static const std::string flag_MYCUS_OK("MYCUS_OK")
static const std::string flag_CATTLE("CATTLE")
static const trait_id trait_THRESH_LUPINE("THRESH_LUPINE")
static const trait_id trait_THRESH_CATTLE("THRESH_CATTLE")
static const trait_id trait_THRESH_FELINE("THRESH_FELINE")
static const std::string comesttype_FOOD("FOOD")
static const std::string flag_CARNIVORE_OK("CARNIVORE_OK")
static const trait_id trait_WATERSLEEP("WATERSLEEP")
static const std::string flag_FELINE("FELINE")
static const trait_id trait_M_DEPENDENT("M_DEPENDENT")
static const std::string flag_NO_INGEST("NO_INGEST")
static const std::string flag_LUPINE("LUPINE")
std::vector< material_id > materials
Definition: itype.h:924

References _, carnivore_blacklist, comesttype_DRINK(), comesttype_FOOD(), compute_effective_nutrients(), item::count_by_charges(), edible, flag_BIRD(), flag_CARNIVORE_OK(), flag_CATTLE(), flag_FELINE(), flag_INEDIBLE(), flag_LUPINE(), flag_MYCUS_OK(), flag_NO_INGEST(), flag_USE_EAT_VERB(), item::get_comestible(), get_mutations(), visitable< Character >::has_amount(), item::has_any_flag(), has_charges(), item::has_flag(), item::has_own_flag(), has_trait(), herbivore_blacklist(), inedible_mutation, item::is_craft(), item::is_medication(), item::is_null(), Creature::is_underwater(), item::made_of_any(), ret_val< T >::make_failure(), ret_val< T >::make_success(), itype::materials, item::nname(), no_tool, string_format(), trait_CARNIVORE, trait_HERBIVORE, trait_M_DEPENDENT, trait_PROBOSCIS, trait_RUMINANT, trait_THRESH_BIRD, trait_THRESH_CATTLE, trait_THRESH_FELINE, trait_THRESH_LUPINE, trait_WATERSLEEP, and item::type.

Referenced by can_feed_furnace_with(), can_feed_reactor_with(), eat(), and will_eat().

◆ can_estimate_rot()

bool Character::can_estimate_rot ( ) const

True if the character has enough skill (in cooking or survival) to estimate time to rot.

Definition at line 1484 of file consumption.cpp.

1485{
1487}
static const skill_id skill_survival("survival")
static const skill_id skill_cooking("cooking")

References get_skill_level(), skill_cooking, and skill_survival.

Referenced by get_freshness_description().

◆ can_feed_furnace_with()

bool Character::can_feed_furnace_with ( const item it) const

Definition at line 1308 of file consumption.cpp.

1309{
1310 if( !it.flammable() || it.has_flag( flag_RADIOACTIVE ) || can_eat( it ).success() ) {
1311 return false;
1312 }
1313
1314 if( !has_active_bionic( bio_furnace ) ) {
1315 return false;
1316 }
1317
1318 // Not even one charge fits
1319 if( it.charges_per_volume( furnace_max_volume ) < 1 ) {
1320 return false;
1321 }
1322
1323 return !it.has_flag( flag_CORPSE );
1324}
ret_val< edible_rating > can_eat(const item &food) const
Can the food be [theoretically] eaten no matter the consequen ces?
bool flammable(int threshold=0) const
Whether the items is flammable.
Definition: item.cpp:8321
int charges_per_volume(const units::volume &vol) const
Number of (charges of) this item that fit into the given volume.
Definition: item.cpp:864
const units::volume furnace_max_volume(3_liter)
static const bionic_id bio_furnace("bio_furnace")
static const std::string flag_CORPSE("CORPSE")
static const std::string flag_RADIOACTIVE("RADIOACTIVE")

References bio_furnace, can_eat(), item::charges_per_volume(), flag_CORPSE(), flag_RADIOACTIVE(), item::flammable(), furnace_max_volume, has_active_bionic(), item::has_flag(), and behavior::success.

Referenced by feed_furnace_with(), and get_cbm_rechargeable_with().

◆ can_feed_reactor_with()

bool Character::can_feed_reactor_with ( const item it) const

Determine character's capability of recharging their CBMs.

Definition at line 1261 of file consumption.cpp.

1262{
1263 static const std::set<ammotype> acceptable = {{
1264 ammotype( "reactor_slurry" ),
1265 ammotype( "plutonium" )
1266 }
1267 };
1268
1269 if( !it.is_ammo() || can_eat( it ).success() ) {
1270 return false;
1271 }
1272
1274 return false;
1275 }
1276
1277 return std::any_of( acceptable.begin(), acceptable.end(), [ &it ]( const ammotype & elem ) {
1278 return it.ammo_type() == elem;
1279 } );
1280}
bool is_ammo() const
Definition: item.cpp:6587
static const bionic_id bio_reactor("bio_reactor")
static const bionic_id bio_advreactor("bio_advreactor")
string_id< ammunition_type > ammotype
Definition: type_id.h:12

References bio_advreactor, bio_reactor, can_eat(), has_active_bionic(), item::is_ammo(), and behavior::success.

Referenced by feed_reactor_with(), and get_cbm_rechargeable_with().

◆ can_fuel_bionic_with()

bool Character::can_fuel_bionic_with ( const item it) const

Returns true if the character can fuel a bionic with the item.

Definition at line 1830 of file character.cpp.

1831{
1832 if( !it.is_fuel() ) {
1833 return false;
1834 }
1835
1836 for( const bionic_id &bid : get_bionics() ) {
1837 for( const itype_id &fuel : bid->fuel_opts ) {
1838 if( fuel == it.typeId() ) {
1839 return true;
1840 }
1841 }
1842 }
1843 return false;
1844}
const itype_id & typeId() const
return the unique identifier of the items underlying type
Definition: item.cpp:8358
bool is_fuel() const
Definition: item.cpp:6765

References get_bionics(), item::is_fuel(), and item::typeId().

Referenced by fuel_bionic_with(), and get_cbm_rechargeable_with().

◆ can_hear()

bool Character::can_hear ( const tripoint source,
int  volume 
) const

Definition at line 10235 of file character.cpp.

10236{
10237 if( is_deaf() ) {
10238 return false;
10239 }
10240
10241 // source is in-ear and at our square, we can hear it
10242 if( source == pos() && volume == 0 ) {
10243 return true;
10244 }
10245 const int dist = rl_dist( source, pos() );
10246 const float volume_multiplier = hearing_ability();
10247 return ( volume - get_weather().weather_id->sound_attn ) * volume_multiplier >= dist;
10248}
float hearing_ability() const
bool is_deaf() const
Definition: character.cpp:4474
quantity< int, volume_in_milliliter_tag > volume
Definition: units_volume.h:16

References get_weather(), hearing_ability(), is_deaf(), pos(), and rl_dist().

Referenced by game::chat(), iuse::geiger(), iuse::play_music(), iuse::talking_doll(), and musical_instrument_actor::use().

◆ can_install_bionics()

bool Character::can_install_bionics ( const itype type,
player installer,
bool  autodoc = false,
int  skill_level = -1 
)

Is the installation possible.

Definition at line 2145 of file bionics.cpp.

2147{
2148 if( !type.bionic ) {
2149 debugmsg( "Tried to install NULL bionic" );
2150 return false;
2151 }
2152 if( is_mounted() ) {
2153 return false;
2154 }
2155
2156 const bionic_id &bioid = type.bionic->id;
2157 const int difficult = type.bionic->difficulty;
2158 float adjusted_skill;
2159
2160 if( autodoc ) {
2161 adjusted_skill = installer.bionics_adjusted_skill( skill_firstaid,
2164 skill_level );
2165 } else {
2166 adjusted_skill = installer.bionics_adjusted_skill( skill_electronics,
2169 skill_level );
2170 }
2171 int chance_of_success = bionic_manip_cos( adjusted_skill, difficult );
2172
2173 std::vector<std::string> conflicting_muts;
2174 for( const trait_id &mid : bioid->canceled_mutations ) {
2175 if( has_trait( mid ) ) {
2176 conflicting_muts.push_back( mid->name() );
2177 }
2178 }
2179
2180 if( !conflicting_muts.empty() &&
2181 !query_yn(
2182 _( "Installing this bionic will remove the conflicting traits: %s. Continue anyway?" ),
2183 enumerate_as_string( conflicting_muts ) ) ) {
2184 return false;
2185 }
2186
2187 const std::map<bodypart_id, int> &issues = bionic_installation_issues( bioid );
2188 // show all requirements which are not satisfied
2189 if( !issues.empty() ) {
2190 std::string detailed_info;
2191 for( auto &elem : issues ) {
2192 //~ <Body part name>: <number of slots> more slot(s) needed.
2193 detailed_info += string_format( _( "\n%s: %i more slot(s) needed." ),
2194 body_part_name_as_heading( elem.first->token, 1 ),
2195 elem.second );
2196 }
2197 popup( _( "Not enough space for bionic installation!%s" ), detailed_info );
2198 return false;
2199 }
2200
2201 if( chance_of_success >= 100 ) {
2202 if( !g->u.query_yn(
2203 _( "Are you sure you wish to install the selected bionic?" ),
2204 100 - chance_of_success ) ) {
2205 return false;
2206 }
2207 } else {
2208 if( autodoc ) {
2209 if( !g->u.query_yn(
2210 _( "WARNING: There is a %i percent chance of complications, such as damage or faulty installation! Continue anyway?" ),
2211 ( 100 - chance_of_success ) ) ) {
2212 return false;
2213 }
2214 } else {
2215 if( !g->u.query_yn(
2216 _( "WARNING: There is a %i percent chance of complications, such as damage or faulty installation! The following skills affect self-installation: First Aid, Electronics, and Mechanics.\n\nContinue anyway?" ),
2217 ( 100 - chance_of_success ) ) ) {
2218 return false;
2219 }
2220 }
2221 }
2222
2223 return true;
2224}
int bionic_manip_cos(float adjusted_skill, int bionic_difficulty)
Definition: bionics.cpp:1883
static const skill_id skill_mechanics("mechanics")
static const skill_id skill_computer("computer")
static const skill_id skill_firstaid("firstaid")
static const skill_id skill_electronics("electronics")
std::string body_part_name_as_heading(body_part bp, int number)
Returns the name of the body parts in a context where the name is used as a heading or title e....
Definition: bodypart.cpp:341
std::map< bodypart_id, int > bionic_installation_issues(const bionic_id &bioid) const
Definition: bionics.cpp:2494
float bionics_adjusted_skill(const skill_id &most_important_skill, const skill_id &important_skill, const skill_id &least_important_skill, int skill_level=-1)
Calculate skill for (un)installing bionics.
Definition: bionics.cpp:1840
void autodoc(player &p, const tripoint &examp)
Definition: iexamine.cpp:4870
int popup(const std::string &text, PopupFlags flags)
Definition: output.cpp:764
std::string enumerate_as_string(const _Container &values, enumeration_conjunction conj=enumeration_conjunction::and_)
Definition: output.h:680
std::vector< trait_id > canceled_mutations
Mutations/trait that are removed upon installing this CBM.
Definition: bionics.h:106
std::string name() const

References _, iexamine::autodoc(), bionic_installation_issues(), bionic_manip_cos(), bionics_adjusted_skill(), body_part_name_as_heading(), bionic_data::canceled_mutations, debugmsg, enumerate_as_string(), g, has_trait(), is_mounted(), mutation_branch::name(), popup(), query_yn(), skill_computer, skill_electronics, skill_firstaid, skill_mechanics, string_format(), and type.

Referenced by iexamine::autodoc(), and install_bionic_actor::use().

◆ can_install_cbm_on_bp()

bool Character::can_install_cbm_on_bp ( const std::vector< bodypart_id > &  bps) const

Definition at line 456 of file mutation.cpp.

457{
458 bool can_install = true;
459 for( const trait_id &mut : get_mutations() ) {
460 for( const bodypart_id &bp : bps ) {
461 if( mut.obj().no_cbm_on_bp.count( bp.id() ) ) {
462 can_install = false;
463 break;
464 }
465 }
466 }
467 return can_install;
468}

References get_mutations().

Referenced by bionic_install_preset::get_denial().

◆ can_learn_by_disassembly()

bool Character::can_learn_by_disassembly ( const recipe rec) const

Definition at line 10563 of file character.cpp.

10564{
10565 return !rec.learn_by_disassembly.empty() &&
10567}
bool meets_skill_requirements(const std::map< skill_id, int > &req, const item &context=item()) const
Checks whether the character's skills meet the required.
Definition: character.cpp:3485
std::map< skill_id, int > learn_by_disassembly
Definition: recipe.h:111

References recipe::learn_by_disassembly, and meets_skill_requirements().

Referenced by crafting::complete_disassemble().

◆ can_miss_recovery()

bool Character::can_miss_recovery ( const item weap) const

Returns true if the player is able to use a miss recovery technique.

Definition at line 943 of file martialarts.cpp.

944{
945 if( !martial_arts_data->has_miss_recovery_tec( weap ) ) {
946 return false;
947 }
948
949 ma_technique tec = martial_arts_data->get_miss_recovery_tec( weap );
950
951 return tec.is_valid_character( *this );
952}
bool is_valid_character(const Character &u) const

References ma_technique::is_valid_character(), and martial_arts_data.

Referenced by melee_attack().

◆ can_mount()

bool Character::can_mount ( const monster critter) const

Definition at line 565 of file monexamine.cpp.

566{
567 const auto &avoid = get_path_avoid();
568 auto route = get_map().route( pos(), critter.pos(), get_pathfinding_settings(), avoid );
569
570 if( route.empty() ) {
571 return false;
572 }
573 return ( critter.has_flag( MF_PET_MOUNTABLE ) && critter.friendly == -1 &&
574 !critter.has_effect( effect_ai_waiting ) && !critter.has_effect( effect_ridden ) ) &&
575 ( ( critter.has_effect( effect_saddled ) && get_skill_level( skill_survival ) >= 1 ) ||
576 get_skill_level( skill_survival ) >= 4 ) && ( critter.get_size() >= ( get_size() + 1 ) &&
577 get_weight() <= critter.get_weight() * critter.get_mountable_weight_ratio() );
578}
units::mass get_weight() const override
Returns body weight plus weight of inventory and worn/wielded items.
Definition: character.cpp:3652
std::set< tripoint > get_path_avoid() const override
Returns a set of points we do not want to path through.
Definition: character.cpp:9907
m_size get_size() const override
Get size class of character.
Definition: character.cpp:561
const pathfinding_settings & get_pathfinding_settings() const override
Returns settings for pathfinding.
Definition: character.cpp:9921
std::vector< tripoint > route(const tripoint &f, const tripoint &t, const pathfinding_settings &settings, const std::set< tripoint > &pre_closed={{ }}) const
Calculate the best path using A*.
bool has_flag(m_flag f) const override
Definition: monster.cpp:898
m_size get_size() const override
Definition: monster.cpp:2701
const tripoint & pos() const override
Definition: monster.cpp:256
units::mass get_weight() const override
Definition: monster.cpp:2706
float get_mountable_weight_ratio() const
Definition: monster.cpp:2931
static const efftype_id effect_ai_waiting("ai_waiting")
static const efftype_id effect_ridden("ridden")
static const efftype_id effect_saddled("monster_saddled")
static const skill_id skill_survival("survival")
@ MF_PET_MOUNTABLE
Definition: mtype.h:164

References effect_ai_waiting, effect_ridden, effect_saddled, monster::friendly, get_map(), monster::get_mountable_weight_ratio(), get_path_avoid(), get_pathfinding_settings(), get_size(), monster::get_size(), get_skill_level(), get_weight(), monster::get_weight(), Creature::has_effect(), monster::has_flag(), MF_PET_MOUNTABLE, pos(), monster::pos(), map::route(), and skill_survival.

Referenced by talk_function::find_mount(), activity_handlers::find_mount_do_turn(), and monexamine::pet_menu().

◆ can_pick_volume() [1/2]

bool Character::can_pick_volume ( const item it) const

Definition at line 2675 of file character.cpp.

2676{
2677 inventory projected = inv;
2678 projected.add_item( it, true );
2679 return projected.volume() <= volume_capacity();
2680}
item & add_item(item newit, bool keep_invlet=false, bool assign_invlet=true, bool should_stack=true)
Definition: inventory.cpp:286
units::volume volume() const
Definition: inventory.cpp:1060

References inventory::add_item(), inv, inventory::volume(), and volume_capacity().

Referenced by avatar_funcs::add_or_drop_with_msg(), pickup_inventory_preset::get_denial(), give_item_to(), handle_harvest(), handle_problematic_pickup(), i_add_or_drop(), npc::mug_player(), pick_one_up(), conditional_t< T >::set_can_stow_weapon(), set_item_inventory(), and starting_inv().

◆ can_pick_volume() [2/2]

bool Character::can_pick_volume ( units::volume  volume) const

Definition at line 2682 of file character.cpp.

2683{
2684 // Might not be 100% true because some items restack to a very tiny bit less
2685 // but close enough not to matter
2686 return inv.volume() + volume <= volume_capacity();
2687}

References inv, inventory::volume(), and volume_capacity().

◆ can_pick_weight() [1/2]

bool Character::can_pick_weight ( const item it,
bool  safe = true 
) const

Definition at line 2689 of file character.cpp.

2690{
2691 return can_pick_weight( it.weight(), safe );
2692}
bool can_pick_weight(const item &it, bool safe=true) const
Definition: character.cpp:2689
units::mass weight(bool include_contents=true, bool integral=false) const
Definition: item.cpp:4947
void safe(player &p, const tripoint &examp)
Attempt to crack safe through audio-feedback manual lock manipulation.
Definition: iexamine.cpp:1417

References can_pick_weight(), iexamine::safe(), and item::weight().

Referenced by avatar_funcs::add_or_drop_with_msg(), can_pick_weight(), pickup_inventory_preset::get_denial(), give_item_to(), handle_harvest(), i_add_or_drop(), npc::mug_player(), pick_one_up(), and set_item_inventory().

◆ can_pick_weight() [2/2]

bool Character::can_pick_weight ( units::mass  weight,
bool  safe = true 
) const

Definition at line 2694 of file character.cpp.

2695{
2696 if( !safe ) {
2697 // Character can carry up to four times their maximum weight
2698 return ( weight_carried() + weight <= ( has_trait( trait_DEBUG_STORAGE ) ?
2699 units::mass_max : weight_capacity() * 4 ) );
2700 } else {
2701 return ( weight_carried() + weight <= weight_capacity() );
2702 }
2703}
static const trait_id trait_DEBUG_STORAGE("DEBUG_STORAGE")
constexpr mass mass_max
Definition: units_mass.h:27

References has_trait(), units::mass_max, iexamine::safe(), trait_DEBUG_STORAGE, weight_capacity(), and weight_carried().

◆ can_reload()

bool Character::can_reload ( const item it,
const itype_id ammo = itype_id() 
) const

Whether a tool or gun is potentially reloadable (optionally considering a specific ammo)

Parameters
itThing to be reloaded
ammoif set also check item currently compatible with this specific ammo or magazine
Note
items currently loaded with a detachable magazine are considered reloadable
items with integral magazines are reloadable if free capacity permits (+/- ammo matches)

Definition at line 10880 of file character.cpp.

10881{
10882 if( !it.is_reloadable_with( ammo ) ) {
10883 return false;
10884 }
10885
10886 if( it.is_ammo_belt() ) {
10887 const auto &linkage = it.type->magazine->linkage;
10888 if( linkage && !has_charges( *linkage, 1 ) ) {
10889 return false;
10890 }
10891 }
10892
10893 return true;
10894}
bool is_reloadable_with(const itype_id &ammo) const
Returns true if this item can be reloaded with specified ammo type at this moment.
Definition: item.cpp:6871
bool is_ammo_belt() const
Definition: item.cpp:6572
cata::value_ptr< islot_magazine > magazine
Definition: itype.h:861

References has_charges(), item::is_ammo_belt(), item::is_reloadable_with(), itype::magazine, and item::type.

Referenced by can_reload_item_or_mods(), npc::find_usable_ammo(), character_funcs::list_ammo(), examine_item_menu::rate_action_reload(), ammobelt_actor::use(), and wants_to_reload().

◆ can_run()

bool Character::can_run ( )

source of truth of whether a Character can run

Definition at line 1250 of file character.cpp.

1251{
1252 return ( get_stamina() > get_stamina_max() * 0.1f ) && get_working_leg_count() >= 2;
1253}

References get_stamina(), get_stamina_max(), and get_working_leg_count().

Referenced by game::on_move_effects(), and avatar::set_movement_mode().

◆ can_swap()

ret_val< bool > Character::can_swap ( const item it) const

Check player capable of swapping the side of a worn item.

Parameters
itThing to be swapped

Definition at line 3125 of file character.cpp.

3126{
3127 if( it.has_flag( flag_POWERARMOR_MOD ) ) {
3128 int max_layer = 2;
3129 std::vector< std::pair< body_part, int > > mod_parts;
3130 body_part bp = num_bp;
3131 bodypart_str_id bpid;
3132 for( std::size_t i = 0; i < static_cast< body_part >( num_bp ); ++i ) {
3133 bp = static_cast< body_part >( i );
3134 bpid = convert_bp( bp );
3135 if( it.get_covered_body_parts().test( bp ) && bpid->part_side != side::BOTH ) {
3136 mod_parts.emplace_back( bp, 0 );
3137 }
3138 }
3139 for( auto &elem : worn ) {
3140 for( std::pair< body_part, int > &mod_part : mod_parts ) {
3141 bpid = convert_bp( mod_part.first );
3142 if( elem.get_covered_body_parts().test( bpid->opposite_part->token ) &&
3143 elem.has_flag( flag_POWERARMOR_MOD ) ) {
3144 mod_part.second++;
3145 }
3146 }
3147 }
3148 for( std::pair< body_part, int > &mod_part : mod_parts ) {
3149 bpid = convert_bp( mod_part.first );
3150 if( mod_part.second >= max_layer ) {
3151 return ret_val<bool>::make_failure( _( "There is no space on the opposite side!" ) );
3152 }
3153 }
3154 }
3155
3157}
const bodypart_str_id & convert_bp(body_part bp)
Returns the new id for old token.
Definition: bodypart.cpp:185
static const std::string flag_POWERARMOR_MOD("POWERARMOR_MOD")
side part_side
Definition: bodypart.h:124
body_part token
Definition: bodypart.h:106
bodypart_str_id opposite_part
Definition: bodypart.h:122

References _, BOTH, convert_bp(), flag_POWERARMOR_MOD(), item::get_covered_body_parts(), item::has_flag(), ret_val< T >::make_failure(), ret_val< T >::make_success(), num_bp, body_part_type::opposite_part, body_part_type::part_side, body_part_set::test(), body_part_type::token, and worn.

Referenced by change_side().

◆ can_takeoff()

ret_val< bool > Character::can_takeoff ( const item it,
const std::list< item > *  res = nullptr 
) const

Check if character is capable of taking off given item.

Parameters
itItem to be taken off
resIf set, will expect to move item into the list.

Definition at line 2988 of file character.cpp.

2989{
2990 auto iter = std::find_if( worn.begin(), worn.end(), [ &it ]( const item & wit ) {
2991 return &it == &wit;
2992 } );
2993
2994 if( iter == worn.end() ) {
2995 return ret_val<bool>::make_failure( !is_npc() ? _( "You are not wearing that item." ) :
2996 _( "<npcname> is not wearing that item." ) );
2997 }
2998
2999 if( res == nullptr && !get_dependent_worn_items( it ).empty() ) {
3001 _( "You can't take off power armor while wearing other power armor components." ) :
3002 _( "<npcname> can't take off power armor while wearing other power armor components." ) );
3003 }
3004 if( it.has_flag( "NO_TAKEOFF" ) ) {
3006 _( "You can't take that item off." ) :
3007 _( "<npcname> can't take that item off." ) );
3008 }
3010}
std::list< item * > get_dependent_worn_items(const item &it) const
Returns all items that must be taken off before taking off this item.
Definition: character.cpp:2396

References _, get_dependent_worn_items(), item::has_flag(), Creature::is_npc(), ret_val< T >::make_failure(), ret_val< T >::make_success(), and worn.

Referenced by drop(), take_off_inventory_preset::get_denial(), avatar_action::plthrow(), examine_item_menu::rate_action_takeoff(), examine_item_menu::run(), takeoff(), and avatar_action::wield().

◆ can_uninstall_bionic()

bool Character::can_uninstall_bionic ( const bionic_id b_id,
player installer,
bool  autodoc = false,
int  skill_level = -1 
)

Is The uninstallation possible.

Definition at line 1904 of file bionics.cpp.

1906{
1907 // If malfunctioning bionics doesn't have associated item it gets predefined difficulty
1908 int difficulty = BIONIC_NOITEM_DIFFICULTY;
1909 if( b_id->itype().is_valid() ) {
1910 const itype *type = &*b_id->itype();
1911 if( type->bionic ) {
1912 difficulty = type->bionic->difficulty;
1913 }
1914 }
1915
1916 if( !has_bionic( b_id ) ) {
1917 popup( _( "%s don't have this bionic installed." ), disp_name() );
1918 return false;
1919 }
1920
1921 if( ( b_id == bio_reactor ) || ( b_id == bio_advreactor ) ) {
1922 if( !g->u.query_yn(
1923 _( "WARNING: Removing a reactor may leave radioactive material! Remove anyway?" ) ) ) {
1924 return false;
1925 }
1926 }
1927
1928 for( const bionic_id &bid : get_bionics() ) {
1929 if( bid->is_included( b_id ) ) {
1930 popup( _( "%s must remove the %s bionic to remove the %s." ), installer.disp_name(),
1931 bid->name, b_id->name );
1932 return false;
1933 }
1934 }
1935
1936 if( b_id == bio_eye_optic ) {
1937 popup( _( "The Telescopic Lenses are part of %s eyes now. Removing them would leave %s blind." ),
1938 disp_name( true ), disp_name() );
1939 return false;
1940 }
1941
1942 // removal of bionics adds +2 difficulty over installation
1943 float adjusted_skill;
1944 if( autodoc ) {
1945 adjusted_skill = installer.bionics_adjusted_skill( skill_firstaid,
1948 skill_level );
1949 } else {
1950 adjusted_skill = installer.bionics_adjusted_skill( skill_electronics,
1953 skill_level );
1954 }
1955 int chance_of_success = bionic_manip_cos( adjusted_skill, difficulty + 2 );
1956
1957 if( chance_of_success >= 100 ) {
1958 if( !g->u.query_yn(
1959 _( "Are you sure you wish to uninstall the selected bionic?" ),
1960 100 - chance_of_success ) ) {
1961 return false;
1962 }
1963 } else {
1964 if( !g->u.query_yn(
1965 _( "WARNING: %i percent chance of SEVERE damage to all body parts! Continue anyway?" ),
1966 ( 100 - static_cast<int>( chance_of_success ) ) ) ) {
1967 return false;
1968 }
1969 }
1970
1971 return true;
1972}
static const bionic_id bio_reactor("bio_reactor")
constexpr int BIONIC_NOITEM_DIFFICULTY
Definition: bionics.cpp:209
static const bionic_id bio_eye_optic("bio_eye_optic")
static const bionic_id bio_advreactor("bio_advreactor")
bool is_valid() const
Returns whether this id is valid, that means whether it refers to an existing object.
Definition: achievement.cpp:65
itype_id itype() const
Definition: bionics.cpp:247
Definition: itype.h:836

References _, iexamine::autodoc(), bio_advreactor, bio_eye_optic, bio_reactor, bionic_manip_cos(), BIONIC_NOITEM_DIFFICULTY, bionics_adjusted_skill(), disp_name(), g, get_bionics(), has_bionic(), string_id< T >::is_valid(), bionic_data::itype(), bionic_data::name, popup(), skill_computer, skill_electronics, skill_firstaid, skill_mechanics, and type.

Referenced by iexamine::autodoc().

◆ can_unwield()

ret_val< bool > Character::can_unwield ( const item it) const

Check whether character is capable of unwielding given item.

Definition at line 3095 of file character.cpp.

3096{
3097 if( it.has_flag( "NO_UNWIELD" ) ) {
3098 return ret_val<bool>::make_failure( _( "You cannot unwield your %s." ), it.tname() );
3099 }
3100
3102}

References _, item::has_flag(), ret_val< T >::make_failure(), ret_val< T >::make_success(), and item::tname().

Referenced by apply_damage(), drop(), inv_dump(), examine_item_menu::run(), unwield(), and avatar_action::wield().

◆ can_use()

bool Character::can_use ( const item it,
const item context = item() 
) const

Checks if character stats and skills meet minimum requirements for the item.

Prints an appropriate message if requirements not met.

Parameters
itItem we are checking
contextoptionally override effective item when checking contextual skills

Definition at line 2705 of file character.cpp.

2706{
2707 const auto &ctx = !context.is_null() ? context : it;
2708
2709 if( !meets_requirements( it, ctx ) ) {
2710 const std::string unmet( enumerate_unmet_requirements( it, ctx ) );
2711
2712 if( &it == &ctx ) {
2713 //~ %1$s - list of unmet requirements, %2$s - item name.
2714 add_msg_player_or_npc( m_bad, _( "You need at least %1$s to use this %2$s." ),
2715 _( "<npcname> needs at least %1$s to use this %2$s." ),
2716 unmet, it.tname() );
2717 } else {
2718 //~ %1$s - list of unmet requirements, %2$s - item name, %3$s - indirect item name.
2719 add_msg_player_or_npc( m_bad, _( "You need at least %1$s to use this %2$s with your %3$s." ),
2720 _( "<npcname> needs at least %1$s to use this %2$s with their %3$s." ),
2721 unmet, it.tname(), ctx.tname() );
2722 }
2723
2724 return false;
2725 }
2726
2727 return true;
2728}
std::string enumerate_unmet_requirements(const item &it, const item &context=item()) const
Returns a string of missed requirements (both stats and skills)
Definition: character.cpp:3337
bool meets_requirements(const item &it, const item &context=item()) const
Checks whether the character meets overall requirements to be able to use the item.
Definition: character.cpp:3507

References _, Creature::add_msg_player_or_npc(), enumerate_unmet_requirements(), item::is_null(), m_bad, meets_requirements(), and item::tname().

Referenced by can_use_heal_item(), avatar_funcs::gunmod_add(), ranged::gunmode_checks_common(), and avatar_funcs::toolmod_add().

◆ can_use_floor_warmth()

bool Character::can_use_floor_warmth ( ) const

Can the player lie down and cover self with blankets etc.

Definition at line 9396 of file character.cpp.

9397{
9398 return in_sleep_state() ||
9399 has_activity( activity_id( "ACT_WAIT" ) ) ||
9400 has_activity( activity_id( "ACT_WAIT_NPC" ) ) ||
9401 has_activity( activity_id( "ACT_WAIT_STAMINA" ) ) ||
9402 has_activity( activity_id( "ACT_AUTODRIVE" ) ) ||
9403 has_activity( activity_id( "ACT_READ" ) ) ||
9404 has_activity( activity_id( "ACT_SOCIALIZE" ) ) ||
9405 has_activity( activity_id( "ACT_MEDITATE" ) ) ||
9406 has_activity( activity_id( "ACT_FISH" ) ) ||
9407 has_activity( activity_id( "ACT_GAME" ) ) ||
9408 has_activity( activity_id( "ACT_HAND_CRANK" ) ) ||
9409 has_activity( activity_id( "ACT_HEATING" ) ) ||
9410 has_activity( activity_id( "ACT_VIBE" ) ) ||
9411 has_activity( activity_id( "ACT_TRY_SLEEP" ) ) ||
9412 has_activity( activity_id( "ACT_OPERATION" ) ) ||
9413 has_activity( activity_id( "ACT_TREE_COMMUNION" ) ) ||
9414 has_activity( activity_id( "ACT_EAT_MENU" ) ) ||
9415 has_activity( activity_id( "ACT_CONSUME_FOOD_MENU" ) ) ||
9416 has_activity( activity_id( "ACT_CONSUME_DRINK_MENU" ) ) ||
9417 has_activity( activity_id( "ACT_CONSUME_MEDS_MENU" ) ) ||
9418 has_activity( activity_id( "ACT_STUDY_SPELL" ) );
9419}
string_id< activity_type > activity_id
Definition: activity_type.h:15

References has_activity(), and in_sleep_state().

Referenced by update_bodytemp().

◆ can_use_grab_break_tec()

bool Character::can_use_grab_break_tec ( const item weap) const

Returns true if the player is able to use a grab breaking technique.

Definition at line 932 of file martialarts.cpp.

933{
934 if( !has_grab_break_tec() ) {
935 return false;
936 }
937
938 ma_technique tec = martial_arts_data->get_grab_break_tec( weap );
939
940 return tec.is_valid_character( *this );
941}
bool has_grab_break_tec() const override
Returns true if the player has a grab breaking technique available.

References has_grab_break_tec(), ma_technique::is_valid_character(), and martial_arts_data.

Referenced by mattack::grab().

◆ can_use_heal_item()

bool Character::can_use_heal_item ( const item med) const

Check for mutation disallowing the use of an healing item.

Definition at line 424 of file mutation.cpp.

425{
426 const itype_id heal_id = med.typeId();
427
428 bool can_use = false;
429 bool got_restriction = false;
430
431 for( const trait_id &mut : get_mutations() ) {
432 if( !mut.obj().can_only_heal_with.empty() ) {
433 got_restriction = true;
434 }
435 if( mut.obj().can_only_heal_with.count( heal_id ) ) {
436 can_use = true;
437 break;
438 }
439 }
440 if( !got_restriction ) {
441 can_use = !med.has_flag( "CANT_HEAL_EVERYONE" );
442 }
443
444 if( !can_use ) {
445 for( const trait_id &mut : get_mutations() ) {
446 if( mut.obj().can_heal_with.count( heal_id ) ) {
447 can_use = true;
448 break;
449 }
450 }
451 }
452
453 return can_use;
454}
bool can_use(const item &it, const item &context=item()) const
Checks if character stats and skills meet minimum requirements for the item.
Definition: character.cpp:2705

References can_use(), get_mutations(), item::has_flag(), and item::typeId().

Referenced by activatable_inventory_preset::get_denial(), and heal_actor::use_healing_item().

◆ can_wear()

ret_val< bool > Character::can_wear ( const item it,
bool  with_equip_change = false 
) const

Check character capable of wearing an item.

Parameters
itThing to be worn
with_equip_changeIf true returns if it could be worn if things were taken off

Definition at line 2730 of file character.cpp.

2731{
2732 if( !it.is_armor() ) {
2733 return ret_val<bool>::make_failure( _( "Putting on a %s would be tricky." ), it.tname() );
2734 }
2735
2736 if( has_trait( trait_WOOLALLERGY ) && ( it.made_of( material_id( "wool" ) ) ||
2737 it.has_own_flag( "wooled" ) ) ) {
2738 return ret_val<bool>::make_failure( _( "Can't wear that, it's made of wool!" ) );
2739 }
2740
2741 if( it.is_filthy() && has_trait( trait_SQUEAMISH ) ) {
2742 return ret_val<bool>::make_failure( _( "Can't wear that, it's filthy!" ) );
2743 }
2744
2745 if( !it.has_flag( flag_OVERSIZE ) && !it.has_flag( flag_SEMITANGIBLE ) ) {
2746 for( const trait_id &mut : get_mutations() ) {
2747 const auto &branch = mut.obj();
2748 if( branch.conflicts_with_item( it ) ) {
2750 _( "Your %s mutation prevents you from wearing your %s." ) :
2751 _( "My %s mutation prevents me from wearing this %s." ), branch.name(),
2752 it.type_name() );
2753 }
2754 }
2755 if( it.covers( bp_head ) && !it.has_flag( flag_SEMITANGIBLE ) &&
2756 !it.made_of( material_id( "wool" ) ) && !it.made_of( material_id( "cotton" ) ) &&
2757 !it.made_of( material_id( "nomex" ) ) && !it.made_of( material_id( "leather" ) ) &&
2759 has_trait( trait_ANTLERS ) ) ) {
2760 return ret_val<bool>::make_failure( _( "Cannot wear a helmet over %s." ),
2761 ( has_trait( trait_HORNS_POINTED ) ? _( "horns" ) :
2762 ( has_trait( trait_ANTENNAE ) ? _( "antennae" ) : _( "antlers" ) ) ) );
2763 }
2764 }
2765
2766 if( it.has_flag( flag_SPLINT ) ) {
2767 bool need_splint = false;
2768 for( const bodypart_id &bp : get_all_body_parts() ) {
2769 if( !it.covers( bp->token ) ) {
2770 continue;
2771 }
2772 if( is_limb_broken( bp ) && !worn_with_flag( flag_SPLINT, bp ) ) {
2773 need_splint = true;
2774 break;
2775 }
2776 }
2777 if( !need_splint ) {
2779 _( "You don't have any broken limbs this could help." )
2780 : _( "%s doesn't have any broken limbs this could help." ), name );
2781 }
2782 }
2783
2784 if( it.has_flag( flag_RESTRICT_HANDS ) && !has_two_arms() ) {
2785 return ret_val<bool>::make_failure( ( is_player() ? _( "You don't have enough arms to wear that." )
2786 : string_format( _( "%s doesn't have enough arms to wear that." ), name ) ) );
2787 }
2788
2789 //Everything checked after here should be something that could be solved by changing equipment
2790 if( with_equip_change ) {
2792 }
2793
2794 if( it.is_power_armor() ) {
2795 for( auto &elem : worn ) {
2796 if( ( elem.get_covered_body_parts() & it.get_covered_body_parts() ).any() &&
2797 !elem.has_flag( flag_POWERARMOR_COMPATIBLE ) && !elem.is_power_armor() ) {
2798 return ret_val<bool>::make_failure( _( "Can't wear power armor over other gear!" ) );
2799 } else if( elem.has_flag( flag_POWERARMOR_EXO ) && it.has_flag( flag_POWERARMOR_EXO ) ) {
2800 return ret_val<bool>::make_failure( _( "Can't wear multiple exoskeletons!" ) );
2801 }
2802 }
2805 _( "You can only wear power armor components with power armor!" ) );
2806 }
2808 for( auto &elem : worn ) {
2809 if( elem.has_flag( flag_POWERARMOR_EXO ) &&
2810 ( elem.get_covered_body_parts() & it.get_covered_body_parts() ).any() ) {
2811 return ret_val<bool>::make_failure( _( "Can't wear externals over an exoskeleton!" ) );
2812 } else if( elem.has_flag( flag_POWERARMOR_EXTERNAL ) &&
2813 ( elem.get_covered_body_parts() & it.get_covered_body_parts() ).any() ) {
2814 return ret_val<bool>::make_failure( _( "Can't wear externals over one another!" ) );
2815 }
2816 }
2817 }
2818 if( it.has_flag( flag_POWERARMOR_MOD ) ) {
2819 int max_layer = 2;
2820 std::vector< std::pair< body_part, int > > mod_parts;
2821 std::vector< std::pair< body_part, bool > > attachments;
2822 body_part bp = num_bp;
2823 bodypart_str_id bpid;
2824 bool lhs = false;
2825 bool rhs = false;
2826 for( std::size_t i = 0; i < static_cast< body_part >( num_bp ); ++i ) {
2827 bp = static_cast< body_part >( i );
2828 if( it.get_covered_body_parts().test( bp ) ) {
2829 mod_parts.emplace_back( bp, 0 );
2830 attachments.emplace_back( bp, false );
2831 }
2832 }
2833 for( auto &elem : worn ) {
2834 // To check if there's an external/exoskeleton for the mod to attach to.
2835 for( std::pair< body_part, bool > &attachment : attachments ) {
2836 if( elem.get_covered_body_parts().test( attachment.first ) &&
2837 ( elem.has_flag( flag_POWERARMOR_EXO ) || elem.has_flag( flag_POWERARMOR_EXTERNAL ) ) ) {
2838 if( elem.is_sided() && elem.get_side() == bpid->part_side ) {
2839 attachment.second = true;
2840 } else {
2841 attachment.second = true;
2842 }
2843 }
2844 }
2845 // To check how many mods are on a given part.
2846 for( std::pair< body_part, int > &mod_part : mod_parts ) {
2847 bpid = convert_bp( mod_part.first );
2848 if( elem.get_covered_body_parts().test( mod_part.first ) &&
2849 elem.has_flag( flag_POWERARMOR_MOD ) ) {
2850 if( elem.is_sided() && elem.get_side() == bpid->part_side ) {
2851 mod_part.second++;
2852 } else {
2853 mod_part.second++;
2854 }
2855 }
2856 }
2857 }
2858 for( std::pair< body_part, bool > &attachment : attachments ) {
2859 if( !attachment.second ) {
2860 return ret_val<bool>::make_failure( _( "Nothing to attach the mod to!" ) );
2861 }
2862 }
2863 for( std::pair< body_part, int > &mod_part : mod_parts ) {
2864 bpid = convert_bp( mod_part.first );
2865 if( static_cast< body_part >( mod_part.first ) == bp_torso ) {
2866 max_layer = 3;
2867 }
2868 if( mod_part.second >= max_layer ) {
2869 if( !it.is_sided() || bpid->part_side == side::BOTH ) {
2870 return ret_val<bool>::make_failure( _( "Can't wear any more mods on that body part!" ) );
2871 } else {
2872 if( bpid->part_side == side::LEFT ) {
2873 lhs = true;
2874 } else {
2875 rhs = true;
2876 }
2877 if( lhs && rhs ) {
2878 return ret_val<bool>::make_failure( _( "No more space for that mod!" ) );
2879 }
2880 }
2881 }
2882 }
2883 }
2884 } else {
2885 // Only headgear can be worn with power armor, except other power armor components.
2886 // You can't wear headgear if power armor helmet is already sitting on your head.
2887 for( auto &elem : worn ) {
2889 ( elem.get_covered_body_parts() & it.get_covered_body_parts() ).any() ) ) {
2890 return ret_val<bool>::make_failure( _( "Can't wear %s with power armor!" ), it.tname() );
2891 }
2892 }
2893 }
2894
2895 // Check if we don't have both hands available before wearing a briefcase, shield, etc. Also occurs if we're already wearing one.
2897 weapon.is_two_handed( *this ) ) ) {
2898 return ret_val<bool>::make_failure( ( is_player() ? _( "You don't have a hand free to wear that." )
2899 : string_format( _( "%s doesn't have a hand free to wear that." ), name ) ) );
2900 }
2901
2902 for( auto &i : worn ) {
2903 if( i.has_flag( flag_ONLY_ONE ) && i.typeId() == it.typeId() ) {
2904 return ret_val<bool>::make_failure( _( "Can't wear more than one %s!" ), it.tname() );
2905 }
2906 }
2907
2908 if( amount_worn( it.typeId() ) >= MAX_WORN_PER_TYPE ) {
2909 return ret_val<bool>::make_failure( _( "Can't wear %i or more %s at once." ),
2910 MAX_WORN_PER_TYPE + 1, it.tname( MAX_WORN_PER_TYPE + 1 ) );
2911 }
2912
2913 if( ( ( it.covers( bp_foot_l ) && is_wearing_shoes( side::LEFT ) ) ||
2914 ( it.covers( bp_foot_r ) && is_wearing_shoes( side::RIGHT ) ) ) &&
2915 ( !it.has_flag( flag_OVERSIZE ) || !it.has_flag( flag_OUTER ) ) && !it.has_flag( flag_SKINTIGHT ) &&
2916 !it.has_flag( flag_BELTED ) && !it.has_flag( flag_PERSONAL ) && !it.has_flag( flag_AURA ) &&
2917 !it.has_flag( flag_SEMITANGIBLE ) ) {
2918 // Checks to see if the player is wearing shoes
2919 return ret_val<bool>::make_failure( ( is_player() ? _( "You're already wearing footwear!" )
2920 : string_format( _( "%s is already wearing footwear!" ), name ) ) );
2921 }
2922
2923 if( it.covers( bp_head ) &&
2925 !it.has_flag( flag_PERSONAL ) && !it.is_power_armor() &&
2927 is_wearing_helmet() ) {
2929 ( is_player() ? _( "You can't wear that with other headgear!" )
2930 : string_format( _( "%s can't wear that with other headgear!" ), name ) ) );
2931 }
2932
2933 if( it.covers( bp_head ) && !it.has_flag( flag_SEMITANGIBLE ) &&
2935 ( head_cloth_encumbrance() + it.get_encumber( *this ) > 40 ) ) {
2936 return ret_val<bool>::make_failure( ( is_player() ? _( "You can't wear that much on your head!" )
2937 : string_format( _( "%s can't wear that much on their head!" ), name ) ) );
2938 }
2939
2941}
static const std::string flag_BELTED("BELTED")
static const trait_id trait_ANTLERS("ANTLERS")
static const trait_id trait_WOOLALLERGY("WOOLALLERGY")
static const trait_id trait_HORNS_POINTED("HORNS_POINTED")
static const std::string flag_SKINTIGHT("SKINTIGHT")
static const std::string flag_POWERARMOR_COMPATIBLE("POWERARMOR_COMPATIBLE")
static const trait_id trait_ANTENNAE("ANTENNAE")
static const std::string flag_HELMET_COMPAT("HELMET_COMPAT")
static const std::string flag_POWERARMOR_EXO("POWERARMOR_EXO")
static const std::string flag_OUTER("OUTER")
static const std::string flag_OVERSIZE("OVERSIZE")
static const std::string flag_ONLY_ONE("ONLY_ONE")
static const std::string flag_POWERARMOR_EXTERNAL("POWERARMOR_EXTERNAL")
static const std::string flag_RESTRICT_HANDS("RESTRICT_HANDS")
static const trait_id trait_SQUEAMISH("SQUEAMISH")
bool is_wearing_power_armor(bool *hasHelmet=nullptr) const
Returns true if the character is wearing power armor.
Definition: character.cpp:3771
bool is_wearing_helmet() const
Returns true if the character is wearing something occupying the helmet slot.
Definition: character.cpp:8854
int amount_worn(const itype_id &id) const
Returns the amount of item ‘type’ that is currently worn.
Definition: character.cpp:2159
bool has_two_arms() const
Returns true if the player has two functioning arms.
Definition: character.cpp:1201
int head_cloth_encumbrance() const
Returns the total encumbrance of all SKINTIGHT and HELMET_COMPAT items coveringi the head.
Definition: character.cpp:8866
bool is_wearing_shoes(const side &which_side=side::BOTH) const
Returns true if the player is wearing something on their feet that is not SKINTIGHT.
Definition: character.cpp:8825
bool is_sided() const
Returns true if item is armor and can be worn on different sides of the body.
Definition: item.cpp:802
bool is_filthy() const
Marks the item as filthy, so characters with squeamish trait can't wear it.
Definition: item.cpp:9981
std::string type_name(unsigned int quantity=1) const
Name of the item type (not the item), with proper plural.
Definition: item.cpp:9851
bool is_power_armor() const
Whether this is a power armor item.
Definition: item.cpp:5791
bool is_armor() const
Definition: item.cpp:6709
int get_encumber(const Character &) const
Returns the encumbrance value that this item has when worn by given player.
Definition: item.cpp:5797
bool is_two_handed(const Character &guy) const
Whether the character needs both hands to wield this item.
Definition: item.cpp:6409
static constexpr int MAX_WORN_PER_TYPE

References _, amount_worn(), BOTH, bp_foot_l, bp_foot_r, bp_head, bp_torso, convert_bp(), item::covers(), flag_AURA(), flag_BELTED(), flag_HELMET_COMPAT(), flag_ONLY_ONE(), flag_OUTER(), flag_OVERSIZE(), flag_PERSONAL(), flag_POWERARMOR_COMPATIBLE(), flag_POWERARMOR_EXO(), flag_POWERARMOR_EXTERNAL(), flag_POWERARMOR_MOD(), flag_RESTRICT_HANDS(), flag_SEMITANGIBLE(), flag_SKINTIGHT(), flag_SPLINT(), Creature::get_all_body_parts(), item::get_covered_body_parts(), item::get_encumber(), get_mutations(), item::has_flag(), item::has_own_flag(), has_trait(), has_two_arms(), head_cloth_encumbrance(), item::is_armor(), item::is_filthy(), is_limb_broken(), Creature::is_player(), item::is_power_armor(), item::is_sided(), item::is_two_handed(), is_wearing_helmet(), is_wearing_power_armor(), is_wearing_shoes(), LEFT, item::made_of(), ret_val< T >::make_failure(), ret_val< T >::make_success(), MAX_WORN_PER_TYPE, name, num_bp, body_part_type::part_side, RIGHT, string_format(), body_part_set::test(), item::tname(), trait_ANTENNAE, trait_ANTLERS, trait_HORNS_POINTED, trait_SQUEAMISH, trait_WOOLALLERGY, item::type_name(), item::typeId(), weapon, wearing_something_on(), worn, and worn_with_flag().

Referenced by behavior::character_oracle_t::can_wear_warmer_clothes(), dispose_item(), wear_inventory_preset::get_denial(), give_item_to(), handle_problematic_pickup(), examine_item_menu::rate_action_wear(), spell_effect::spawn_ethereal_item(), starting_clothes(), avatar_funcs::use_item(), npc::wear_if_wanted(), and wear_item().

◆ can_wield()

ret_val< bool > Character::can_wield ( const item it) const

Check whether character is capable of wielding given item.

Definition at line 3056 of file character.cpp.

3057{
3058 if( it.made_of( LIQUID ) ) {
3059 return ret_val<bool>::make_failure( _( "Can't wield spilt liquids." ) );
3060 }
3061
3062 if( get_working_arm_count() <= 0 ) {
3064 _( "You need at least one arm to even consider wielding something." ) );
3065 }
3066
3067 if( is_armed() && weapon.has_flag( "NO_UNWIELD" ) ) {
3068 return ret_val<bool>::make_failure( _( "The %s is preventing you from wielding the %s." ),
3070 }
3071
3072 monster *mount = mounted_creature.get();
3073 if( it.is_two_handed( *this ) && ( !has_two_arms() || worn_with_flag( flag_RESTRICT_HANDS ) ) &&
3074 !( is_mounted() && mount->has_flag( MF_RIDEABLE_MECH ) &&
3075 mount->type->mech_weapon && it.typeId() == mount->type->mech_weapon ) ) {
3078 _( "Something you are wearing hinders the use of both hands." ) );
3079 } else if( it.has_flag( "ALWAYS_TWOHAND" ) ) {
3080 return ret_val<bool>::make_failure( _( "The %s can't be wielded with only one arm." ),
3081 it.tname() );
3082 } else {
3083 return ret_val<bool>::make_failure( _( "You are too weak to wield %s with only one arm." ),
3084 it.tname() );
3085 }
3086 }
3087 if( is_mounted() && mount->has_flag( MF_RIDEABLE_MECH ) &&
3088 mount->type->mech_weapon && it.typeId() != mount->type->mech_weapon ) {
3089 return ret_val<bool>::make_failure( _( "You cannot wield anything while piloting a mech." ) );
3090 }
3091
3093}
int get_working_arm_count() const
Returns the number of functioning arms.
Definition: character.cpp:1208
bool is_armed() const
Returns true if the character is wielding something.
Definition: melee.cpp:148
const mtype * type
Definition: monster.h:477
@ LIQUID
Definition: enums.h:175
std::string fmt_wielded_weapon(const Character &who)
Get the formatted name of the currently wielded item (if any) with current gun mode (if gun)
itype_id mech_weapon
If this monster is a rideable mech with built-in weapons, this is the weapons id.
Definition: mtype.h:368

References _, flag_RESTRICT_HANDS(), character_funcs::fmt_wielded_weapon(), get_working_arm_count(), item::has_flag(), monster::has_flag(), has_two_arms(), is_armed(), is_mounted(), item::is_two_handed(), LIQUID, item::made_of(), ret_val< T >::make_failure(), ret_val< T >::make_success(), mtype::mech_weapon, MF_RIDEABLE_MECH, mounted_creature, item::tname(), monster::type, item::typeId(), weapon, and worn_with_flag().

Referenced by apply_damage(), find_best_bench(), weapon_inventory_preset::get_denial(), pick_one_up(), character_funcs::try_wield_contents(), avatar::wield(), and avatar_action::wield().

◆ cancel_activity()

void Character::cancel_activity ( )

Definition at line 9188 of file character.cpp.

9189{
9190 activity.canceled( *this );
9191 if( has_activity( ACT_MOVE_ITEMS ) && is_hauling() ) {
9192 stop_hauling();
9193 }
9194 if( has_activity( ACT_TRY_SLEEP ) ) {
9195 remove_value( "sleep_query" );
9196 }
9197 // Clear any backlog items that aren't auto-resume.
9198 for( auto backlog_item = backlog.begin(); backlog_item != backlog.end(); ) {
9199 if( backlog_item->auto_resume ) {
9200 backlog_item++;
9201 } else {
9202 backlog_item = backlog.erase( backlog_item );
9203 }
9204 }
9205 // act wait stamina interrupts an ongoing activity.
9206 // and automatically puts auto_resume = true on it
9207 // we don't want that to persist if there is another interruption.
9208 // and player moves elsewhere.
9209 if( has_activity( ACT_WAIT_STAMINA ) && !backlog.empty() &&
9210 backlog.front().auto_resume ) {
9211 backlog.front().auto_resume = false;
9212 }
9213 if( activity && activity.is_suspendable() ) {
9214 backlog.push_front( activity );
9215 }
9216 sfx::end_activity_sounds(); // kill activity sounds when canceled
9218}
static const activity_id ACT_TRY_SLEEP("ACT_TRY_SLEEP")
static const activity_id ACT_MOVE_ITEMS("ACT_MOVE_ITEMS")
static const activity_id ACT_WAIT_STAMINA("ACT_WAIT_STAMINA")
bool is_hauling() const
Definition: character.cpp:9140
void stop_hauling()
Definition: character.cpp:9131
void canceled(Character &who)
Performs activity-specific cleanup when Character::cancel_activity() is called.
bool is_suspendable() const
If this returns true, the action can be continued without starting from scratch again (see player::ba...
void end_activity_sounds()
Definition: sounds.cpp:1603

References ACT_MOVE_ITEMS, ACT_TRY_SLEEP, ACT_WAIT_STAMINA, activity, backlog, player_activity::canceled(), sfx::end_activity_sounds(), has_activity(), is_hauling(), player_activity::is_suspendable(), Creature::remove_value(), and stop_hauling().

Referenced by activity_on_turn_move_loot(), activity_on_turn_wear(), activity_handlers::adv_inventory_do_turn(), activity_handlers::armor_layers_do_turn(), activity_handlers::build_do_turn(), player::can_continue_craft(), game::cancel_activity_or_ignore_query(), game::cancel_activity_query(), activity_handlers::craft_do_turn(), autodrive_activity_actor::do_turn(), drop_activity_actor::do_turn(), stash_activity_actor::do_turn(), pickup_activity_actor::do_turn(), avatar_action::eat(), fall_asleep(), game::forced_door_closing(), item::handle_craft_failure(), mattack::pull_metal_weapon(), npc::reboot(), DefaultRemovePartHandler::removed(), show_armor_layers_ui(), autodrive_activity_actor::start(), activity_handlers::start_fire_do_turn(), stop_hauling(), and npc::talk_to_u().

◆ cancel_stashed_activity()

void Character::cancel_stashed_activity ( )

◆ change_side() [1/2]

bool Character::change_side ( item it,
bool  interactive = true 
)

Swap side on which item is worn; returns false on fail.

If interactive is false, don't alert player or drain moves

Definition at line 3683 of file character.cpp.

3684{
3685 const auto ret = can_swap( it );
3686 if( !ret.success() ) {
3687 if( interactive ) {
3688 add_msg_if_player( m_info, "%s", ret.c_str() );
3689 }
3690 return false;
3691 }
3692
3693 if( !it.swap_side() ) {
3694 if( interactive ) {
3696 _( "You cannot swap the side on which your %s is worn." ),
3697 _( "<npcname> cannot swap the side on which their %s is worn." ),
3698 it.tname() );
3699 }
3700 return false;
3701 }
3702
3703 if( interactive ) {
3704 add_msg_player_or_npc( m_info, _( "You swap the side on which your %s is worn." ),
3705 _( "<npcname> swaps the side on which their %s is worn." ),
3706 it.tname() );
3707 }
3708
3709 mod_moves( -250 );
3711
3712 return true;
3713}
ret_val< bool > can_swap(const item &it) const
Check player capable of swapping the side of a worn item.
Definition: character.cpp:3125
bool swap_side()
Swap the side on which the item is worn.
Definition: item.cpp:830

References _, Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), can_swap(), m_info, Creature::mod_moves(), reset_encumbrance(), cata::hash64_detail::ret, item::swap_side(), and item::tname().

Referenced by npc::adjust_worn(), change_side(), examine_item_menu::run(), and show_armor_layers_ui().

◆ change_side() [2/2]

bool Character::change_side ( item_location loc,
bool  interactive = true 
)

Definition at line 3715 of file character.cpp.

3716{
3717 if( !loc || !is_worn( *loc ) ) {
3718 if( interactive ) {
3720 _( "You are not wearing that item." ),
3721 _( "<npcname> isn't wearing that item." ) );
3722 }
3723 return false;
3724 }
3725
3726 return change_side( *loc, interactive );
3727}
bool is_worn(const item &thing) const
Definition: character.h:1086
bool change_side(item &it, bool interactive=true)
Swap side on which item is worn; returns false on fail.
Definition: character.cpp:3683

References _, Creature::add_msg_player_or_npc(), change_side(), is_worn(), and m_info.

◆ check_and_recover_morale()

bool Character::check_and_recover_morale ( )

Checks permanent morale for consistency and recovers it when an inconsistency is found.

Definition at line 9083 of file character.cpp.

9084{
9085 player_morale test_morale;
9086
9087 for( const item &wit : worn ) {
9088 test_morale.on_item_wear( wit );
9089 }
9090
9091 for( const trait_id &mut : get_mutations() ) {
9092 test_morale.on_mutation_gain( mut );
9093 }
9094
9095 for( const auto &elem : *effects ) {
9096 for( const std::pair<const bodypart_str_id, effect> &_effect_it : elem.second ) {
9097 const effect &e = _effect_it.second;
9098 if( !e.is_removed() ) {
9099 test_morale.on_effect_int_change( e.get_id(), e.get_intensity(), e.get_bp() );
9100 }
9101 }
9102 }
9103
9104 test_morale.on_stat_change( "kcal", get_stored_kcal() );
9105 test_morale.on_stat_change( "thirst", get_thirst() );
9106 test_morale.on_stat_change( "fatigue", get_fatigue() );
9107 test_morale.on_stat_change( "pain", get_pain() );
9108 test_morale.on_stat_change( "pkill", get_painkiller() );
9109 test_morale.on_stat_change( "perceived_pain", get_perceived_pain() );
9110
9112
9113 if( !morale->consistent_with( test_morale ) ) {
9114 *morale = player_morale( test_morale ); // Recover consistency
9115 add_msg( m_debug, "%s morale was recovered.", disp_name( true ) );
9116 return false;
9117 }
9118
9119 return true;
9120}
int get_fatigue() const
Definition: character.cpp:4443
int get_thirst() const
Definition: character.cpp:4315
void apply_persistent_morale()
Ensures persistent morale effects are up-to-date.
Definition: character.cpp:8962
pimpl< effects_map > effects
Definition: creature.h:812
const efftype_id & get_id() const
Returns the effect's matching effect_type id.
Definition: effect.h:305
int get_intensity() const
Returns the intensity of an effect.
Definition: effect.cpp:849
const bodypart_str_id & get_bp() const
Returns the targeted body_part of the effect.
Definition: effect.cpp:835
bool is_removed() const
Returns if the effect is disabled and set up for removal.
Definition: effect.h:246
void on_item_wear(const item &it)
Definition: morale.cpp:935
void on_stat_change(const std::string &stat, int value)
Definition: morale.cpp:927
void on_effect_int_change(const efftype_id &eid, int intensity, const bodypart_str_id &bp=bodypart_str_id::NULL_ID())
Definition: morale.cpp:974
void on_mutation_gain(const trait_id &mid)
Definition: morale.cpp:917

References add_msg(), apply_persistent_morale(), disp_name(), Creature::effects, effect::get_bp(), get_fatigue(), effect::get_id(), effect::get_intensity(), get_mutations(), Creature::get_pain(), get_painkiller(), get_perceived_pain(), get_stored_kcal(), get_thirst(), effect::is_removed(), m_debug, morale, player_morale::on_effect_int_change(), player_morale::on_item_wear(), player_morale::on_mutation_gain(), player_morale::on_stat_change(), and worn.

Referenced by game::do_turn().

◆ check_item_encumbrance_flag()

void Character::check_item_encumbrance_flag ( )

Checks worn items for the "RESET_ENCUMBRANCE" flag, which indicates that encumbrance may have changed and require recalculating.

Definition at line 1748 of file character.cpp.

1749{
1750 bool update_required = check_encumbrance;
1751 for( auto &i : worn ) {
1752 if( !update_required && i.encumbrance_update_ ) {
1753 update_required = true;
1754 }
1755 i.encumbrance_update_ = false;
1756 }
1757
1758 if( update_required ) {
1760 }
1761}
bool check_encumbrance
Definition: character.h:2226

References check_encumbrance, reset_encumbrance(), and worn.

◆ check_mount_is_spooked()

bool Character::check_mount_is_spooked ( )

Definition at line 1023 of file character.cpp.

1024{
1025 if( !is_mounted() ) {
1026 return false;
1027 }
1028 // chance to spook per monster nearby:
1029 // base 1% per turn.
1030 // + 1% per square closer than 15 distanace. (1% - 15%)
1031 // * 2 if hostile monster is bigger than or same size as mounted creature.
1032 // -0.25% per point of dexterity (low -1%, average -2%, high -3%, extreme -3.5%)
1033 // -0.1% per point of strength ( low -0.4%, average -0.8%, high -1.2%, extreme -1.4% )
1034 // / 2 if horse has full tack and saddle.
1035 // Monster in spear reach monster and average stat (8) player on saddled horse, 14% -2% -0.8% / 2 = ~5%
1036 if( mounted_creature && mounted_creature->type->has_fear_trigger( mon_trigger::HOSTILE_CLOSE ) ) {
1037 const m_size mount_size = mounted_creature->get_size();
1038 const bool saddled = mounted_creature->has_effect( effect_saddled );
1039 for( const monster &critter : g->all_monsters() ) {
1040 double chance = 1.0;
1041 Attitude att = critter.attitude_to( *this );
1042 // actually too close now - horse might spook.
1043 if( att == A_HOSTILE && sees( critter ) && rl_dist( pos(), critter.pos() ) <= 10 ) {
1044 chance += 10 - rl_dist( pos(), critter.pos() );
1045 if( critter.get_size() >= mount_size ) {
1046 chance *= 2;
1047 }
1048 chance -= 0.25 * get_dex();
1049 chance -= 0.1 * get_str();
1050 if( saddled ) {
1051 chance /= 2;
1052 }
1053 chance = std::max( 1.0, chance );
1054 if( x_in_y( chance, 100.0 ) ) {
1056 return true;
1057 }
1058 }
1059 }
1060 }
1061 return false;
1062}
bool x_in_y(const time_duration &a, const time_duration &b)
Definition: calendar.cpp:521
static const efftype_id effect_saddled("monster_saddled")
virtual int get_dex() const
Definition: character.cpp:4056
void forced_dismount()
Definition: character.cpp:1069
Attitude
Simplified attitude towards any creature: hostile - hate, want to kill, etc.
Definition: creature.h:166
m_size
Definition: creature.h:57

References Creature::A_HOSTILE, effect_saddled, forced_dismount(), g, get_dex(), get_str(), HOSTILE_CLOSE, is_mounted(), mounted_creature, pos(), rl_dist(), sees(), and x_in_y().

Referenced by game::do_turn().

◆ check_mount_will_move()

bool Character::check_mount_will_move ( const tripoint dest_loc)

Definition at line 1005 of file character.cpp.

1006{
1007 if( !is_mounted() ) {
1008 return true;
1009 }
1010 if( mounted_creature && mounted_creature->type->has_fear_trigger( mon_trigger::HOSTILE_CLOSE ) ) {
1011 for( const monster &critter : g->all_monsters() ) {
1012 Attitude att = critter.attitude_to( *this );
1013 if( att == A_HOSTILE && sees( critter ) && rl_dist( pos(), critter.pos() ) <= 15 &&
1014 rl_dist( dest_loc, critter.pos() ) < rl_dist( pos(), critter.pos() ) ) {
1015 add_msg_if_player( _( "You fail to budge your %s!" ), mounted_creature->get_name() );
1016 return false;
1017 }
1018 }
1019 }
1020 return true;
1021}

References _, Creature::A_HOSTILE, Creature::add_msg_if_player(), g, HOSTILE_CLOSE, is_mounted(), mounted_creature, pos(), rl_dist(), and sees().

Referenced by avatar_action::move().

◆ check_needs_extremes()

void Character::check_needs_extremes ( )

Kills the player if too hungry, stimmed up etc., forces tired player to sleep and prints warnings.

Intelligence slightly decreases occurrence of short naps when dead tired Intelligence slightly decreases occurrence of short naps when exhausted Perception slightly decreases occurrence of short naps when sleep deprived Perception slightly increases resilience against passing out from sleep deprivation

Definition at line 4960 of file character.cpp.

4961{
4962 // Check if we've overdosed... in any deadly way.
4963 if( get_stim() > 250 ) {
4964 add_msg_if_player( m_bad, _( "You have a sudden heart attack!" ) );
4965 g->events().send<event_type::dies_from_drug_overdose>( getID(), efftype_id() );
4966 set_part_hp_cur( bodypart_id( "torso" ), 0 );
4967 } else if( get_stim() < -200 || get_painkiller() > 240 ) {
4968 add_msg_if_player( m_bad, _( "Your breathing stops completely." ) );
4969 g->events().send<event_type::dies_from_drug_overdose>( getID(), efftype_id() );
4970 set_part_hp_cur( bodypart_id( "torso" ), 0 );
4971 } else if( has_effect( effect_jetinjector ) && get_effect_dur( effect_jetinjector ) > 40_minutes ) {
4972 if( !( has_trait( trait_NOPAIN ) ) ) {
4973 add_msg_if_player( m_bad, _( "Your heart spasms painfully and stops." ) );
4974 } else {
4975 add_msg_if_player( _( "Your heart spasms and stops." ) );
4976 }
4978 set_part_hp_cur( bodypart_id( "torso" ), 0 );
4979 } else if( get_effect_dur( effect_adrenaline ) > 50_minutes ) {
4980 add_msg_if_player( m_bad, _( "Your heart spasms and stops." ) );
4982 set_part_hp_cur( bodypart_id( "torso" ), 0 );
4983 } else if( get_effect_int( effect_drunk ) > 4 ) {
4984 add_msg_if_player( m_bad, _( "Your breathing slows down to a stop." ) );
4986 set_part_hp_cur( bodypart_id( "torso" ), 0 );
4987 }
4988
4989 // check if we've starved
4990 if( is_player() ) {
4991 if( get_stored_kcal() <= 0 ) {
4992 add_msg_if_player( m_bad, _( "You have starved to death." ) );
4993 g->events().send<event_type::dies_of_starvation>( getID() );
4994 set_part_hp_cur( bodypart_id( "torso" ), 0 );
4995 } else if( calendar::once_every( 6_hours ) ) {
4996 std::string category;
4997 if( get_kcal_percent() < 0.1f ) {
4998 category = "empty_starving";
4999 } else if( get_kcal_percent() < 0.25f ) {
5000 category = "empty_emaciated";
5001 } else if( get_kcal_percent() < 0.5f ) {
5002 category = "empty_malnutrition";
5003 } else if( get_kcal_percent() < 0.7f ) {
5004 category = "empty_low_cal";
5005 }
5006 if( !category.empty() ) {
5007 const translation message = SNIPPET.random_from_category( category ).value_or( translation() );
5009 }
5010
5011 }
5012 }
5013
5014 // Check if we're dying of thirst
5016 if( get_thirst() >= thirst_levels::dead ) {
5017 add_msg_if_player( m_bad, _( "You have died of dehydration." ) );
5018 g->events().send<event_type::dies_of_thirst>( getID() );
5019 set_part_hp_cur( bodypart_id( "torso" ), 0 );
5020 } else if( get_thirst() >= lerp( +thirst_levels::parched, +thirst_levels::dead, 0.333f ) &&
5021 calendar::once_every( 30_minutes ) ) {
5022 add_msg_if_player( m_warning, _( "Even your eyes feel dry…" ) );
5023 } else if( get_thirst() >= lerp( +thirst_levels::parched, +thirst_levels::dead, 0.666f ) &&
5024 calendar::once_every( 30_minutes ) ) {
5025 add_msg_if_player( m_warning, _( "You are THIRSTY!" ) );
5026 } else if( calendar::once_every( 30_minutes ) ) {
5027 add_msg_if_player( m_warning, _( "Your mouth feels so dry…" ) );
5028 }
5029 }
5030
5031 // Check if we're falling asleep, unless we're sleeping
5034 add_msg_if_player( m_bad, _( "Survivor sleep now." ) );
5036 mod_fatigue( -10 );
5037 fall_asleep();
5038 } else if( get_fatigue() >= 800 && calendar::once_every( 30_minutes ) ) {
5039 add_msg_if_player( m_warning, _( "Anywhere would be a good place to sleep…" ) );
5040 } else if( calendar::once_every( 30_minutes ) ) {
5041 add_msg_if_player( m_warning, _( "You feel like you haven't slept in days." ) );
5042 }
5043 }
5044
5045 // Even if we're not Exhausted, we really should be feeling lack/sleep earlier
5046 // Penalties start at Dead Tired and go from there
5048 if( get_fatigue() >= 700 ) {
5049 if( calendar::once_every( 30_minutes ) ) {
5050 add_msg_if_player( m_warning, _( "You're too physically tired to stop yawning." ) );
5051 add_effect( effect_lack_sleep, 30_minutes + 1_turns );
5052 }
5053 /** @EFFECT_INT slightly decreases occurrence of short naps when dead tired */
5054 if( one_in( 50 + int_cur ) ) {
5055 fall_asleep( 30_seconds );
5056 }
5057 } else if( get_fatigue() >= fatigue_levels::exhausted ) {
5058 if( calendar::once_every( 30_minutes ) ) {
5059 add_msg_if_player( m_warning, _( "How much longer until bedtime?" ) );
5060 add_effect( effect_lack_sleep, 30_minutes + 1_turns );
5061 }
5062 /** @EFFECT_INT slightly decreases occurrence of short naps when exhausted */
5063 if( one_in( 100 + int_cur ) ) {
5064 fall_asleep( 30_seconds );
5065 }
5066 } else if( get_fatigue() >= fatigue_levels::dead_tired && calendar::once_every( 30_minutes ) ) {
5067 add_msg_if_player( m_warning, _( "*yawn* You should really get some sleep." ) );
5068 add_effect( effect_lack_sleep, 30_minutes + 1_turns );
5069 }
5070 }
5071
5072 // Sleep deprivation kicks in if lack of sleep is avoided with stimulants or otherwise for long periods of time
5074 float sleep_deprivation_pct = sleep_deprivation / static_cast<float>
5076
5078 calendar::once_every( 60_minutes ) &&
5082 _( "Your mind feels tired. It's been a while since you've slept well." ) );
5083 mod_fatigue( 1 );
5086 _( "Your mind feels foggy from lack of good sleep, and your eyes keep trying to close against your will." ) );
5087 mod_fatigue( 5 );
5088
5089 if( one_in( 10 ) ) {
5090 mod_healthy_mod( -1, 0 );
5091 }
5094 _( "Your mind feels weary, and you dread every wakeful minute that passes. You crave sleep, and feel like you're about to collapse." ) );
5095 mod_fatigue( 10 );
5096
5097 if( one_in( 5 ) ) {
5098 mod_healthy_mod( -2, -20 );
5099 }
5102 _( "You haven't slept decently for so long that your whole body is screaming for mercy. It's a miracle that you're still awake, but it just feels like a curse now." ) );
5103 mod_fatigue( 40 );
5104
5105 mod_healthy_mod( -5, -50 );
5106 }
5107 // else you pass out for 20 hours, guaranteed
5108
5109 // Microsleeps are slightly worse if you're sleep deprived, but not by much. (chance: 1 in (75 + per_cur) at minor sleep deprivation)
5110 // Note: these can coexist with fatigue-related microsleeps
5111 /** @EFFECT_PER slightly decreases occurrence of short naps when sleep deprived */
5112 if( one_in( static_cast<int>( ( 1.0f - sleep_deprivation_pct ) * 75 + get_per() ) ) ) {
5113 fall_asleep( 30_seconds );
5114 }
5115
5116
5119 /** @EFFECT_PER slightly increases resilience against passing out from sleep deprivation */
5120 one_in( static_cast<int>( ( 1.0f - sleep_deprivation_pct ) * 100 ) + get_per() ) ) ) ) {
5122 _( "Your body collapses due to sleep deprivation, your neglected fatigue rushing back all at once, and you pass out on the spot." )
5123 , _( "<npcname> collapses to the ground from exhaustion." ) );
5125 set_fatigue( static_cast<int>( fatigue_levels::exhausted ) );
5126 }
5127
5129 fall_asleep( 20_hours );
5131 fall_asleep( 16_hours );
5132 } else {
5133 fall_asleep( 12_hours );
5134 }
5135 }
5136 }
5137}
constexpr T lerp(const T &min, const T &max, float t)
Linear interpolation: returns first argument if t is 0, second if t is 1, otherwise proportional to t...
Definition: cata_utility.h:155
static const efftype_id effect_lack_sleep("lack_sleep")
static const efftype_id effect_drunk("drunk")
static const efftype_id effect_adrenaline("adrenaline")
static const efftype_id effect_meth("meth")
static const efftype_id effect_jetinjector("jetinjector")
static const trait_id trait_NOPAIN("NOPAIN")
float get_kcal_percent() const
Definition: character.cpp:4310
virtual void set_fatigue(int nfatigue)
Definition: character.cpp:4428
void fall_asleep()
Adds "sleep" to the player.
Definition: character.cpp:9228
virtual void mod_fatigue(int nfatigue)
Definition: character.cpp:4418
int get_stim() const
Definition: character.cpp:7015
virtual void mod_healthy_mod(int nhealthy_mod, int cap)
Definition: character.cpp:4246
int get_sleep_deprivation() const
Definition: character.cpp:4448
virtual int get_per() const
Definition: character.cpp:4060
void set_part_hp_cur(const bodypart_id &id, int set)
Definition: creature.cpp:1581
time_duration get_effect_dur(const efftype_id &eff_id, body_part bp=num_bp) const
Returns the duration of the matching effect.
Definition: creature.cpp:1247
cata::optional< translation > random_from_category(const std::string &cat) const
Returns a random snippet out of the given category.
Class for storing translation context and raw string for deferred translation.
Definition: translations.h:152
@ m_warning
Definition: enums.h:264
@ falls_asleep_from_exhaustion
@ dies_from_drug_overdose
@ dies_of_starvation
bool once_every(const time_duration &event_frequency)
Predicate to handle rate-limiting.
Definition: calendar.cpp:490
std::string message
Definition: mapgen.cpp:411
snippet_library SNIPPET

References _, Creature::add_effect(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), dead, dead_tired, dies_from_drug_overdose, dies_of_starvation, dies_of_thirst, effect_adrenaline, effect_drunk, effect_jetinjector, effect_lack_sleep, effect_meth, efftype_id, exhausted, fall_asleep(), falls_asleep_from_exhaustion, g, Creature::get_effect_dur(), Creature::get_effect_int(), get_fatigue(), get_kcal_percent(), get_painkiller(), get_per(), get_sleep_deprivation(), get_stim(), get_stored_kcal(), get_thirst(), getID(), harmless, Creature::has_effect(), has_trait(), in_sleep_state(), int_cur, Creature::is_player(), lerp(), m_bad, m_warning, major, massive, mapgen_defer::message, minor, mod_fatigue(), mod_healthy_mod(), calendar::once_every(), one_in(), parched, snippet_library::random_from_category(), serious, set_fatigue(), Creature::set_part_hp_cur(), sleep_deprivation, SNIPPET, and trait_NOPAIN.

Referenced by update_body().

◆ check_outbounds_activity()

bool Character::check_outbounds_activity ( const player_activity act,
bool  check_only = false 
)

Definition at line 917 of file character.cpp.

918{
919 map &here = get_map();
920 if( ( act.placement != tripoint_zero && act.placement != tripoint_min &&
921 !here.inbounds( here.getlocal( act.placement ) ) ) || ( !act.coords.empty() &&
922 !here.inbounds( here.getlocal( act.coords.back() ) ) ) ) {
923 if( is_npc() && !check_only ) {
924 // stash activity for when reloaded.
926 if( !backlog.empty() ) {
928 }
930 }
932 "npc %s at pos %d %d, activity target is not inbounds at %d %d therefore activity was stashed",
933 disp_name(), pos().x, pos().y, act.placement.x, act.placement.y );
934 return true;
935 }
936 return false;
937}
tripoint getlocal(const tripoint &p) const
Inverse of getabs.
Definition: map.cpp:8282
virtual bool inbounds(const tripoint &p) const
Definition: map.cpp:7773
static constexpr tripoint tripoint_zero
Definition: point.h:273
static constexpr tripoint tripoint_min
Definition: point.h:318

References act, activity, add_msg(), backlog, disp_name(), get_map(), map::getlocal(), map::inbounds(), Creature::is_npc(), m_debug, pos(), stashed_outbounds_activity, stashed_outbounds_backlog, tripoint_min, and tripoint_zero.

Referenced by player_activity::do_turn(), and npc::move().

◆ clairvoyance()

int Character::clairvoyance ( ) const

Returns the distance the player can see through walls.

Definition at line 675 of file character.cpp.

676{
678 return MAX_CLAIRVOYANCE;
679 }
680
682 return 8;
683 }
684
686 return 3;
687 }
688
689 // 0 would mean we have clairvoyance of own tile
690 return -1;
691}
#define MAX_CLAIRVOYANCE
Definition: character.h:84
@ VISION_CLAIRVOYANCE_PLUS
Definition: character.h:95
@ VISION_CLAIRVOYANCE
Definition: character.h:94
@ VISION_CLAIRVOYANCE_SUPER
Definition: character.h:96
std::bitset< NUM_VISION_MODES > vision_mode_cache
Definition: character.h:2148

References MAX_CLAIRVOYANCE, VISION_CLAIRVOYANCE, VISION_CLAIRVOYANCE_PLUS, VISION_CLAIRVOYANCE_SUPER, and vision_mode_cache.

Referenced by sees().

◆ clear_bionics()

void Character::clear_bionics ( )

Remove all bionics.

Definition at line 2648 of file bionics.cpp.

2649{
2650 my_bionics->clear();
2651}

References my_bionics.

◆ clear_destination()

◆ clear_destination_activity()

void Character::clear_destination_activity ( )

Definition at line 944 of file character.cpp.

945{
947}
player_activity destination_activity
Definition: character.h:2211

References destination_activity.

Referenced by clear_destination().

◆ clear_miss_reasons()

void Character::clear_miss_reasons ( )

Clears the list of reasons for why the player would miss a melee attack.

Definition at line 327 of file melee.cpp.

328{
329 melee_miss_reasons.clear();
330}

References melee_miss_reasons.

Referenced by process_turn().

◆ clear_morale()

void Character::clear_morale ( )

Definition at line 9073 of file character.cpp.

9074{
9075 morale->clear();
9076}

References morale.

◆ clear_mutations()

void Character::clear_mutations ( )

Empties the trait and mutations lists.

Definition at line 2882 of file newcharacter.cpp.

2883{
2884 while( !my_traits.empty() ) {
2885 toggle_trait( *my_traits.begin() );
2886 }
2887 while( !my_mutations.empty() ) {
2888 unset_mutation( my_mutations.begin()->first );
2889 }
2890 cached_mutations.clear();
2891}
void toggle_trait(const trait_id &)
Toggles a trait on the player and in their mutation list.
Definition: mutation.cpp:127
std::vector< const mutation_branch * > cached_mutations
Pointers to mutation branches in my_mutations.
Definition: character.h:2134
void unset_mutation(const trait_id &)
Definition: mutation.cpp:167
std::unordered_set< trait_id > my_traits
Contains mutation ids of the base traits.
Definition: character.h:2130

References cached_mutations, my_mutations, my_traits, toggle_trait(), and unset_mutation().

Referenced by npc::randomize(), and reset_scenario().

◆ clear_npc_ai_info_cache()

void Character::clear_npc_ai_info_cache ( const std::string &  key) const

Definition at line 10583 of file character.cpp.

10584{
10585 npc_ai_info_cache.erase( key );
10586}
std::map< std::string, double > npc_ai_info_cache
Definition: character.h:2244

References npc_ai_info_cache.

Referenced by i_add(), remove_weapon(), npc::wield(), and avatar::wield().

◆ clear_skills()

void Character::clear_skills ( )

Clear the skills map, setting all levels to 0.

Definition at line 2893 of file newcharacter.cpp.

2894{
2895 for( auto &sk : *_skills ) {
2896 sk.second.level( 0 );
2897 }
2898}
pimpl< SkillLevelMap > _skills
Character skills.
Definition: character.h:2141

References _skills.

Referenced by reset_scenario().

◆ compute_effective_nutrients()

nutrients Character::compute_effective_nutrients ( const item comest) const

Definition at line 335 of file consumption.cpp.

336{
337 if( !comest.is_comestible() ) {
338 return {};
339 }
340
341 // if item has components, will derive calories from that instead.
342 if( !comest.components.empty() && !comest.has_flag( flag_NUTRIENT_OVERRIDE ) ) {
343 nutrients tally{};
344 for( const item &component : comest.components ) {
345 nutrients component_value =
347 if( component.has_flag( flag_BYPRODUCT ) ) {
348 tally -= component_value;
349 } else {
350 tally += component_value;
351 }
352 }
353 return tally / comest.recipe_charges;
354 } else {
355 return compute_default_effective_nutrients( comest, *this );
356 }
357}
std::list< item > components
Definition: item.h:2159
int recipe_charges
Definition: item.h:2199
static nutrients compute_default_effective_nutrients(const item &comest, const Character &you, const cata::flat_set< std::string > &extra_flags={})
static const std::string flag_NUTRIENT_OVERRIDE("NUTRIENT_OVERRIDE")
static const std::string flag_BYPRODUCT("BYPRODUCT")

References item::components, compute_default_effective_nutrients(), compute_effective_nutrients(), flag_BYPRODUCT(), flag_NUTRIENT_OVERRIDE(), item::has_flag(), item::is_comestible(), and item::recipe_charges.

Referenced by can_eat(), comestible_inventory_preset::comestible_inventory_preset(), compute_effective_nutrients(), consume_effects(), eat(), find_auto_consume(), item::food_info(), nutrition_for(), and will_eat().

◆ compute_nutrient_range() [1/2]

std::pair< nutrients, nutrients > Character::compute_nutrient_range ( const item comest,
const recipe_id recipe_i,
const cata::flat_set< std::string > &  extra_flags = {} 
) const

Get calorie & vitamin contents for a comestible, taking into account character traits.

Get range of possible nutrient content, for a particular recipe, depending on choice of ingredients

Definition at line 361 of file consumption.cpp.

364{
365 if( !comest.is_comestible() ) {
366 return {};
367 }
368
369 // if item has components, will derive calories from that instead.
370 if( comest.has_flag( flag_NUTRIENT_OVERRIDE ) ) {
372 return { result, result };
373 }
374
375 nutrients tally_min;
376 nutrients tally_max;
377
378 const recipe &rec = *recipe_i;
379
380 cata::flat_set<std::string> our_extra_flags = extra_flags;
381
382 if( rec.hot_result() ) {
383 our_extra_flags.insert( flag_COOKED );
384 }
385
386 const requirement_data requirements = rec.simple_requirements();
387 const requirement_data::alter_item_comp_vector &component_requirements =
388 requirements.get_components();
389
390 for( const std::vector<item_comp> &component_options : component_requirements ) {
391 nutrients this_min;
392 nutrients this_max;
393 bool first = true;
394 for( const item_comp &component_option : component_options ) {
395 std::pair<nutrients, nutrients> component_option_range =
396 compute_nutrient_range( component_option.type, our_extra_flags );
397 component_option_range.first *= component_option.count;
398 component_option_range.second *= component_option.count;
399
400 if( first ) {
401 std::tie( this_min, this_max ) = component_option_range;
402 first = false;
403 } else {
404 this_min.min_in_place( component_option_range.first );
405 this_max.max_in_place( component_option_range.second );
406 }
407 }
408 tally_min += this_min;
409 tally_max += this_max;
410 }
411
412 for( const std::pair<const itype_id, int> &byproduct : rec.byproducts ) {
413 item byproduct_it( byproduct.first, calendar::turn, byproduct.second );
414 nutrients byproduct_nutr = compute_default_effective_nutrients( byproduct_it, *this );
415 tally_min -= byproduct_nutr;
416 tally_max -= byproduct_nutr;
417 }
418
419 int charges = comest.count();
420 return { tally_min / charges, tally_max / charges };
421}
std::pair< nutrients, nutrients > compute_nutrient_range(const item &, const recipe_id &, const cata::flat_set< std::string > &extra_flags={}) const
Get calorie & vitamin contents for a comestible, taking into account character traits.
iterator insert(iterator, const value_type &value)
Definition: flat_set.h:151
int count() const
If count_by_charges(), returns charges, otherwise 1.
Definition: item.cpp:6015
Definition: recipe.h:35
const requirement_data & simple_requirements() const
Fetch combined requirement data (inline and via "using" syntax).
Definition: recipe.h:67
bool hot_result() const
Definition: recipe.cpp:804
std::map< itype_id, int > byproducts
Definition: recipe.h:105
static const std::string flag_COOKED("COOKED")
void min_in_place(const nutrients &r)
Replace the values here with the minimum (or maximum) of themselves and the corresponding values take...
Definition: stomach.cpp:12
void max_in_place(const nutrients &r)
Definition: stomach.cpp:29
The *_vector members represent list of alternatives requirements: alter_tool_comp_vector = { * { { a,...
Definition: requirements.h:215
const alter_item_comp_vector & get_components() const
std::vector< std::vector< item_comp > > alter_item_comp_vector
Definition: requirements.h:223

References recipe::byproducts, compute_default_effective_nutrients(), compute_nutrient_range(), item::count(), flag_COOKED(), flag_NUTRIENT_OVERRIDE(), requirement_data::get_components(), item::has_flag(), recipe::hot_result(), cata::flat_set< T, Compare, Data >::insert(), item::is_comestible(), nutrients::max_in_place(), nutrients::min_in_place(), recipe::simple_requirements(), and calendar::turn.

Referenced by compute_nutrient_range(), and item::food_info().

◆ compute_nutrient_range() [2/2]

std::pair< nutrients, nutrients > Character::compute_nutrient_range ( const itype_id comest_id,
const cata::flat_set< std::string > &  extra_flags = {} 
) const

Same, but across arbitrary recipes.

Definition at line 425 of file consumption.cpp.

427{
428 const itype *comest = &*comest_id;
429 if( !comest->comestible ) {
430 return {};
431 }
432
433 item comest_it( comest, calendar::turn, 1 );
434 // The default nutrients are always a possibility
435 nutrients min_nutr = compute_default_effective_nutrients( comest_it, *this, extra_flags );
436
437 if( comest->has_flag( flag_NUTRIENT_OVERRIDE ) ||
438 recipe_dict.is_item_on_loop( comest->get_id() ) ) {
439 return { min_nutr, min_nutr };
440 }
441
442 nutrients max_nutr = min_nutr;
443
444 for( const recipe_id &rec : comest->recipes ) {
445 nutrients this_min;
446 nutrients this_max;
447
448 item result_it = rec->create_result();
449 if( result_it.contents.num_item_stacks() == 1 ) {
450 const item alt_result = result_it.contents.front();
451 if( alt_result.typeId() == comest_it.typeId() ) {
452 result_it = alt_result;
453 }
454 }
455 if( result_it.typeId() != comest_it.typeId() ) {
456 debugmsg( "When creating recipe result expected %s, got %s\n",
457 comest_it.typeId().str(), result_it.typeId().str() );
458 }
459 std::tie( this_min, this_max ) = compute_nutrient_range( result_it, rec, extra_flags );
460 min_nutr.min_in_place( this_min );
461 max_nutr.max_in_place( this_max );
462 }
463
464 return { min_nutr, max_nutr };
465}
size_t num_item_stacks() const
returns the number of items stacks in contents each item that is not count_by_charges,...
bool is_item_on_loop(const itype_id &) const
item create_result() const
Definition: recipe.cpp:453
recipe_dictionary recipe_dict
cata::value_ptr< islot_comestible > comestible
Definition: itype.h:850
std::vector< recipe_id > recipes
What recipes can make this item.
Definition: itype.h:1016
bool has_flag(const std::string &flag) const
Definition: itype.cpp:71
const itype_id & get_id() const
Definition: itype.h:1065

References itype::comestible, compute_default_effective_nutrients(), compute_nutrient_range(), item::contents, recipe::create_result(), debugmsg, flag_NUTRIENT_OVERRIDE(), item_contents::front(), itype::get_id(), itype::has_flag(), recipe_dictionary::is_item_on_loop(), nutrients::max_in_place(), nutrients::min_in_place(), item_contents::num_item_stacks(), recipe_dict, itype::recipes, string_id< T >::str(), calendar::turn, and item::typeId().

◆ conduct_blood_analysis()

void Character::conduct_blood_analysis ( ) const

Definition at line 1942 of file character.cpp.

1943{
1944 std::vector<std::string> effect_descriptions;
1945 std::vector<nc_color> colors;
1946
1947 for( auto &elem : *effects ) {
1948 if( elem.first->get_blood_analysis_description().empty() ) {
1949 continue;
1950 }
1951 effect_descriptions.emplace_back( elem.first->get_blood_analysis_description() );
1952 colors.emplace_back( elem.first->get_rating() == e_good ? c_green : c_red );
1953 }
1954
1955 const int win_w = 46;
1956 size_t win_h = 0;
1958 ui_adaptor ui;
1959 ui.on_screen_resize( [&]( ui_adaptor & ui ) {
1960 win_h = std::min( static_cast<size_t>( TERMY ),
1961 std::max<size_t>( 1, effect_descriptions.size() ) + 2 );
1962 w = catacurses::newwin( win_h, win_w,
1963 point( ( TERMX - win_w ) / 2, ( TERMY - win_h ) / 2 ) );
1964 ui.position_from_window( w );
1965 } );
1966 ui.mark_resize();
1967 ui.on_redraw( [&]( const ui_adaptor & ) {
1968 draw_border( w, c_red, string_format( " %s ", _( "Blood Test Results" ) ) );
1969 if( effect_descriptions.empty() ) {
1970 trim_and_print( w, point( 2, 1 ), win_w - 3, c_white, _( "No effects." ) );
1971 } else {
1972 for( size_t line = 1; line < ( win_h - 1 ) && line <= effect_descriptions.size(); ++line ) {
1973 trim_and_print( w, point( 2, line ), win_w - 3, colors[line - 1], effect_descriptions[line - 1] );
1974 }
1975 }
1976 wnoutrefresh( w );
1977 } );
1978 input_context ctxt( "BLOOD_TEST_RESULTS" );
1979 ctxt.register_action( "CONFIRM" );
1980 ctxt.register_action( "QUIT" );
1981 ctxt.register_action( "HELP_KEYBINDINGS" );
1982 bool stop = false;
1983 // Display new messages
1984 g->invalidate_main_ui_adaptor();
1985 while( !stop ) {
1987 const std::string action = ctxt.handle_input();
1988 if( action == "CONFIRM" || action == "QUIT" ) {
1989 stop = true;
1990 }
1991 }
1992}
A wrapper over a pointer to a curses window.
Definition: cursesdef.h:55
Represents a context in which a set of actions can be performed.
Definition: input.h:386
Adaptor between UI code and the UI management system.
Definition: ui_manager.h:65
@ action
Definition: dialogue.h:36
@ e_good
Definition: effect.h:29
void line(map *m, const ter_id &type, const point &p1, const point &p2)
Definition: mapgen.cpp:6485
std::string colors()
Definition: path_info.cpp:146
window newwin(int nlines, int ncols, const point &begin)
Definition: ncurses_def.cpp:34
void wnoutrefresh(const window &win)
Definition: ncurses_def.cpp:43
void redraw()
Invalidate the top window and redraw all invalidated windows.
Definition: ui_manager.cpp:389
Definition: overmap_ui.h:17
int TERMX
Definition: output.cpp:47
int TERMY
Definition: output.cpp:48
void trim_and_print(const catacurses::window &w, const point &begin, const int width, const nc_color &base_color, const std::string &text, const report_color_error color_error)
Prints a single line of text.
Definition: output.cpp:214
void draw_border(const catacurses::window &w, nc_color border_color, const std::string &title, nc_color title_color)
Definition: output.cpp:575

References _, action, c_green, c_red, c_white, PATH_INFO::colors(), draw_border(), e_good, Creature::effects, g, input_context::handle_input(), line(), catacurses::newwin(), ui_manager::redraw(), input_context::register_action(), string_format(), TERMX, TERMY, trim_and_print(), and catacurses::wnoutrefresh().

Referenced by activate_bionic(), and iexamine::autodoc().

◆ consume()

void Character::consume ( item_location  loc)

Consume item (food, fuel, medicine, ...) at given location loc .

Definition at line 1577 of file consumption.cpp.

1578{
1579 item &target = *loc;
1580 const bool wielding = is_wielding( target );
1581 const bool worn = is_worn( target );
1582 const bool inv_item = !( wielding || worn );
1583
1584 if( consume_item( target ) ) {
1585
1586 const bool was_in_container = !can_consume_as_is( target );
1587
1588 if( was_in_container ) {
1589 i_rem( &target.contents.front() );
1590 } else {
1591 i_rem( &target );
1592 }
1593
1594 // Restack and sort so that we don't lie about target's invlet
1595 if( inv_item ) {
1596 inv.restack( *this->as_player() );
1597 }
1598
1599 if( was_in_container && wielding ) {
1600 add_msg_if_player( _( "You are now wielding an empty %s." ), weapon.tname() );
1601 } else if( was_in_container && worn ) {
1602 add_msg_if_player( _( "You are now wearing an empty %s." ), target.tname() );
1603 } else if( was_in_container && !is_npc() ) {
1604 bool drop_it = false;
1605 if( get_option<std::string>( "DROP_EMPTY" ) == "no" ) {
1606 drop_it = false;
1607 } else if( get_option<std::string>( "DROP_EMPTY" ) == "watertight" ) {
1608 drop_it = !target.is_watertight_container();
1609 } else if( get_option<std::string>( "DROP_EMPTY" ) == "all" ) {
1610 drop_it = true;
1611 }
1612 if( drop_it ) {
1613 add_msg( _( "You drop the empty %s." ), target.tname() );
1615 } else {
1616 int quantity = inv.const_stack( inv.position_by_item( &target ) ).size();
1617 char letter = target.invlet ? target.invlet : ' ';
1618 add_msg( m_info, _( "%c - %d empty %s" ), letter, quantity, target.tname( quantity ) );
1619 }
1620 }
1621 } else if( inv_item ) {
1622 if( pickup::handle_spillable_contents( *this, target, g->m ) ) {
1623 i_rem( &target );
1624 }
1625 inv.restack( *this->as_player() );
1626 inv.unsort();
1627 }
1628}
bool consume_item(item &target)
Consume given item (food, fuel, medicine, ...).
bool is_wielding(const item &target) const
Definition: character.cpp:3196
void restack(player &p)
Definition: inventory.cpp:399
void unsort()
Definition: inventory.cpp:227
item remove_item(const item *it)
Remove a specific item from the inventory.
Definition: inventory.cpp:718
const std::list< item > & const_stack(int i) const
Definition: inventory.cpp:152
int position_by_item(const item *it) const
Returns the item position of the stack that contains the given item (compared by pointers).
Definition: inventory.cpp:829
bool is_watertight_container() const
Whether this is a container which can be used to store liquids.
Definition: item.cpp:6729
bool handle_spillable_contents(Character &c, item &it, map &m)
If character is handling a potentially spillable bucket, gracefully handle what to do with the conten...
Definition: pickup.cpp:1243

References _, add_msg(), Creature::add_msg_if_player(), Creature::as_player(), can_consume_as_is(), inventory::const_stack(), consume_item(), item::contents, deliberate, item_contents::front(), g, pickup::handle_spillable_contents(), i_rem(), inv, item::invlet, Creature::is_npc(), item::is_watertight_container(), is_wielding(), is_worn(), m_info, inventory::position_by_item(), put_into_vehicle_or_drop(), inventory::remove_item(), inventory::restack(), item::tname(), inventory::unsort(), weapon, and worn.

Referenced by npc::consume_cbm_items(), npc::consume_food(), avatar_action::eat(), avatar_funcs::use_item(), and npc::use_painkiller().

◆ consume_charges()

bool Character::consume_charges ( item used,
int  qty 
)

Consume charges of a tool or comestible item, potentially destroying it in the process.

Parameters
useditem consuming the charges
qtynumber of charges to consume which must be non-zero
Returns
true if item was destroyed

Definition at line 7375 of file character.cpp.

7376{
7377 if( qty < 0 ) {
7378 debugmsg( "Tried to consume negative charges" );
7379 return false;
7380 }
7381
7382 if( qty == 0 ) {
7383 return false;
7384 }
7385
7386 if( !used.is_tool() && !used.is_food() && !used.is_medication() ) {
7387 debugmsg( "Tried to consume charges for non-tool, non-food, non-med item" );
7388 return false;
7389 }
7390
7391 // Consume comestibles destroying them if no charges remain
7392 if( used.is_food() || used.is_medication() ) {
7393 used.charges -= qty;
7394 if( used.charges <= 0 ) {
7395 i_rem( &used );
7396 return true;
7397 }
7398 return false;
7399 }
7400
7401 // Tools which don't require ammo are instead destroyed
7402 if( used.is_tool() && !used.ammo_required() ) {
7403 i_rem( &used );
7404 return true;
7405 }
7406
7407 if( used.is_power_armor() ) {
7408 if( used.charges >= qty ) {
7409 used.ammo_consume( qty, pos() );
7410 } else if( character_funcs::can_interface_armor( *this ) && has_charges( itype_bio_armor, qty ) ) {
7412 } else {
7413 use_charges( itype_UPS, qty );
7414 }
7415 }
7416
7417 // USE_UPS never occurs on base items but is instead added by the UPS tool mod
7418 if( used.has_flag( flag_USE_UPS ) ) {
7419 // With the new UPS system, we'll want to use any charges built up in the tool before pulling from the UPS
7420 // The usage of the item was already approved, so drain item if possible, otherwise use UPS
7421 if( used.charges >= qty ) {
7422 used.ammo_consume( qty, pos() );
7423 } else {
7424 use_charges( itype_UPS, qty );
7425 }
7426 } else {
7427 used.ammo_consume( std::min( qty, used.ammo_remaining() ), pos() );
7428 }
7429 return false;
7430}
static const itype_id itype_UPS("UPS")
static const std::string flag_USE_UPS("USE_UPS")
static const itype_id itype_bio_armor("bio_armor")
std::list< item > use_charges(const itype_id &what, int qty, const std::function< bool(const item &)> &filter=return_true< item >)
Definition: character.cpp:9614
int ammo_remaining() const
Quantity of ammunition currently loaded in tool, gun or auxiliary gunmod.
Definition: item.cpp:7387
bool is_tool() const
Definition: item.cpp:6958
int ammo_required() const
Quantity of ammunition consumed per usage of tool or with each shot of gun.
Definition: item.cpp:7457
bool is_food() const
Definition: item.cpp:6597
int ammo_consume(int qty, const tripoint &pos)
Consume ammo (if available) and return the amount of ammo that was consumed.
Definition: item.cpp:7485
bool can_interface_armor(const Character &who)
Check whether character has an active bionic capable of interfacing with power armor.

References item::ammo_consume(), item::ammo_remaining(), item::ammo_required(), character_funcs::can_interface_armor(), item::charges, debugmsg, flag_USE_UPS(), has_charges(), item::has_flag(), i_rem(), item::is_food(), item::is_medication(), item::is_power_armor(), item::is_tool(), itype_bio_armor, itype_UPS, pos(), and use_charges().

Referenced by chop_plank_activity(), chop_tree_activity(), feedpet(), activity_handlers::firstaid_finish(), npc::heal_player(), npc::heal_self(), invoke_item(), activity_handlers::jackhammer_finish(), petfood(), activity_handlers::pickaxe_finish(), npc::pretend_heal(), activity_handlers::repair_item_finish(), activity_handlers::shear_finish(), and activity_handlers::start_fire_finish().

◆ consume_effects()

bool Character::consume_effects ( item food)

Handles the effects of consuming an item.

Definition at line 1164 of file consumption.cpp.

1165{
1166 if( !food.is_comestible() ) {
1167 debugmsg( "called Character::consume_effects with non-comestible" );
1168 return false;
1169 }
1170
1171 if( has_trait( trait_THRESH_PLANT ) && food.type->can_use( "PLANTBLECH" ) ) {
1172 // Was used to cap nutrition and thirst, but no longer does this
1173 return false;
1174 }
1177 // No good can come of this.
1178 return false;
1179 }
1180
1181 const auto &comest = *food.get_comestible();
1182
1183 // Rotten food causes health loss
1184 const float relative_rot = food.get_relative_rot();
1185 if( relative_rot > 1.0f && !has_trait( trait_SAPROPHAGE ) &&
1187 const float rottedness = clamp( 2 * relative_rot - 2.0f, 0.1f, 1.0f );
1188 // ~-1 health per 1 nutrition at halfway-rotten-away, ~0 at "just got rotten"
1189 // But always round down
1190 int h_loss = -rottedness * comest.get_default_nutr();
1191 mod_healthy_mod( h_loss, -200 );
1192 add_msg( m_debug, "%d health from %0.2f%% rotten food", h_loss, rottedness );
1193 }
1194
1195 // Used in hibernation messages.
1196 const auto nutr = nutrition_for( food );
1197 const bool skip_health = has_trait( trait_PROJUNK2 ) && comest.healthy < 0;
1198 // We can handle junk just fine
1199 if( !skip_health ) {
1200 modify_health( comest );
1201 }
1202 modify_stimulation( comest );
1203 modify_fatigue( comest );
1204 modify_radiation( comest );
1205 modify_addiction( comest );
1206 modify_morale( food, nutr );
1207
1208 // Moved here and changed a bit - it was too complex
1209 // Incredibly minor stuff like this shouldn't require complexity
1210 if( !is_npc() && has_trait( trait_SLIMESPAWNER ) &&
1213 _( "You feel as though you're going to split open! In a good way?" ) );
1214 mod_pain( 5 );
1215 int numslime = 1;
1216 for( int i = 0; i < numslime; i++ ) {
1217 if( monster *const slime = g->place_critter_around( mon_player_blob, pos(), 1 ) ) {
1218 slime->friendly = -1;
1219 }
1220 }
1221 mod_stored_kcal( -400 );
1222 mod_thirst( 40 );
1223 //~ slimespawns have *small voices* which may be the Nice equivalent
1224 //~ of the Rat King's ALL CAPS invective. Probably shared-brain telepathy.
1225 add_msg_if_player( m_good, _( "hey, you look like me! let's work together!" ) );
1226 }
1227
1228 // Set up food for ingestion
1229 const item &contained_food = food.is_container() ? food.get_contained() : food;
1230 food_summary ingested{
1231 compute_effective_nutrients( contained_food )
1232 };
1233 // Maybe move tapeworm to digestion
1234 if( has_effect( effect_tapeworm ) ) {
1235 ingested.nutr /= 2;
1236 }
1237
1238 int excess_kcal = get_stored_kcal() + stomach.get_calories() + ingested.nutr.kcal -
1240
1241 // Moved hypermetabolism check here to prevent it being gimped by various bloating/vomit problems.
1242 if( excess_kcal > 0 && has_trait( trait_EATHEALTH ) ) {
1243 healall( roll_remainder( excess_kcal / 50.0f ) );
1244 mod_stored_kcal( -excess_kcal );
1245 excess_kcal = 0;
1246 }
1247
1248 int excess_quench = -( get_thirst() - comest.quench );
1249 stomach.ingest( ingested );
1250 mod_thirst( -contained_food.type->comestible->quench );
1251
1252
1253 if( ( excess_kcal > 0 || excess_quench > 0 ) && !food.has_flag( flag_NO_BLOAT ) &&
1255 add_effect( effect_bloated, 5_minutes );
1256 }
1257
1258 return true;
1259}
constexpr T clamp(const T &val, const T &min, const T &max)
Clamp first argument so that it is no lower than second and no higher than third.
Definition: cata_utility.h:145
void modify_addiction(const islot_comestible &comest)
Used to apply addiction modifications from food and medication.
void modify_stimulation(const islot_comestible &comest)
Used to apply stimulation modifications from food and medication.
void modify_morale(item &food, int nutr=0)
Used to apply morale modifications from food and medication.
void modify_radiation(const islot_comestible &comest)
Used to apply radiation from food and medication.
virtual void mod_thirst(int nthirst)
Definition: character.cpp:4402
stomach_contents stomach
Definition: character.h:1552
void modify_health(const islot_comestible &comest)
Used to apply health modifications from food and medication.
int nutrition_for(const item &comest) const
Handles the nutrition value for a comestible.
void healall(int dam)
Heals all body parts for dam.
Definition: character.cpp:8609
void modify_fatigue(const islot_comestible &comest)
Used to apply fatigue modifications from food and medication.
bool is_container() const
Whether this is container.
Definition: item.cpp:6724
double get_relative_rot() const
Get rot value relative to shelf life (or 0 if item does not spoil)
Definition: item.cpp:5536
const item & get_contained() const
Return a contained item (if any and only one).
Definition: item.cpp:7051
void ingest(const food_summary &ingested)
Directly adds food to stomach contents.
Definition: stomach.cpp:126
int get_calories() const
Definition: stomach.cpp:179
static const trait_id trait_SLIMESPAWNER("SLIMESPAWNER")
static const mtype_id mon_player_blob("mon_player_blob")
static const trait_id trait_THRESH_PLANT("THRESH_PLANT")
static const bionic_id bio_digestion("bio_digestion")
static const efftype_id effect_tapeworm("tapeworm")
static const trait_id trait_PROJUNK2("PROJUNK2")
static const trait_id trait_SAPROVORE("SAPROVORE")
static const efftype_id effect_bloated("bloated")
static const trait_id trait_EATHEALTH("EATHEALTH")
static const trait_id trait_GOURMAND("GOURMAND")
static const trait_id trait_SAPROPHAGE("SAPROPHAGE")
static const std::string flag_NO_BLOAT("NO_BLOAT")
bool can_use(const std::string &iuse_name) const
Definition: itype.cpp:86

References _, Creature::add_effect(), add_msg(), Creature::add_msg_if_player(), bio_digestion, itype::can_use(), clamp(), itype::comestible, compute_effective_nutrients(), debugmsg, effect_bloated, effect_tapeworm, flag_NO_BLOAT(), g, stomach_contents::get_calories(), item::get_comestible(), item::get_contained(), item::get_relative_rot(), get_stored_kcal(), get_thirst(), item::has_any_flag(), has_bionic(), Creature::has_effect(), item::has_flag(), has_trait(), healall(), herbivore_blacklist(), stomach_contents::ingest(), item::is_comestible(), item::is_container(), Creature::is_npc(), m_debug, m_good, m_mixed, max_stored_kcal(), mod_healthy_mod(), mod_pain(), mod_stored_kcal(), mod_thirst(), modify_addiction(), modify_fatigue(), modify_health(), modify_morale(), modify_radiation(), modify_stimulation(), mon_player_blob, nutrition_for(), pos(), roll_remainder(), slaked, stomach, trait_EATHEALTH, trait_GOURMAND, trait_HERBIVORE, trait_PROJUNK2, trait_RUMINANT, trait_SAPROPHAGE, trait_SAPROVORE, trait_SLIMESPAWNER, trait_THRESH_PLANT, and item::type.

Referenced by consume_med(), eat(), iuse::ecig(), and try_consume().

◆ consume_item()

bool Character::consume_item ( item target)

Consume given item (food, fuel, medicine, ...).

Returns
true if item should be destroyed (last charge was consumed)

Definition at line 1538 of file consumption.cpp.

1539{
1540 if( target.is_null() ) {
1541 add_msg_if_player( m_info, _( "You do not have that item." ) );
1542 return false;
1543 }
1545 add_msg_if_player( m_info, _( "You can't do that while underwater." ) );
1546 return false;
1547 }
1548
1549 item &comest = get_consumable_from( target );
1550
1551 if( comest.is_null() || target.is_craft() ) {
1552 add_msg_if_player( m_info, _( "You can't eat your %s." ), target.tname() );
1553 if( is_npc() ) {
1554 debugmsg( "%s tried to eat a %s", name, target.tname() );
1555 }
1556 return false;
1557 }
1558 if( is_avatar() && !query_consume_ownership( target, *as_avatar() ) ) {
1559 return false;
1560 }
1561 if( consume_med( comest ) ||
1562 eat( comest ) ||
1563 feed_reactor_with( comest ) ||
1564 feed_furnace_with( comest ) ||
1565 fuel_bionic_with( comest ) ) {
1566
1567 if( target.is_container() ) {
1568 target.on_contents_changed();
1569 }
1570
1571 return comest.charges <= 0;
1572 }
1573
1574 return false;
1575}
bool eat(item &food, bool force=false)
Used for eating entered comestible, returns true if comestible is successfully eaten.
bool feed_furnace_with(item &it)
bool fuel_bionic_with(item &it)
item & get_consumable_from(item &it) const
Returns a reference to the item itself (if it's consumable), the first of its contents (if it's consu...
bool feed_reactor_with(item &it)
Recharge CBMs whenever possible.
bool consume_med(item &target)
Consume an item as medication.
virtual bool is_avatar() const
Definition: creature.h:95
void on_contents_changed()
Callback when contents of the item are affected in any way other than just processing.
Definition: item.cpp:4530
static bool query_consume_ownership(item &target, avatar &you)

References _, Creature::add_msg_if_player(), Creature::as_avatar(), item::charges, consume_med(), debugmsg, eat(), feed_furnace_with(), feed_reactor_with(), fuel_bionic_with(), get_consumable_from(), has_trait(), Creature::is_avatar(), item::is_container(), item::is_craft(), Creature::is_npc(), item::is_null(), Creature::is_underwater(), m_info, name, item::on_contents_changed(), query_consume_ownership(), item::tname(), and trait_WATERSLEEP.

Referenced by consume(), and avatar_action::eat().

◆ consume_med()

bool Character::consume_med ( item target)

Consume an item as medication.

Parameters
targetItem consumed. Must be a medication or a container of medication.
Returns
true if item should be destroyed (last charge was consumed)

Definition at line 1631 of file consumption.cpp.

1632{
1633 if( !target.is_medication() ) {
1634 return false;
1635 }
1636
1637 const itype_id tool_type = target.get_comestible()->tool;
1638 const itype *req_tool = &*tool_type;
1639 bool check_tool = true;
1640 if( tool_type == itype_syringe && has_bionic( bio_syringe ) ) {
1641 check_tool = false;
1642 }
1643 if( req_tool->tool ) {
1644 if( check_tool && !(
1645 has_amount( tool_type, 1 ) &&
1646 has_charges( tool_type, req_tool->tool->charges_per_use )
1647 ) ) {
1648 add_msg_if_player( m_info, _( "You need a %s to consume that!" ), req_tool->nname( 1 ) );
1649 return false;
1650 }
1651 use_charges( tool_type, req_tool->tool->charges_per_use );
1652 }
1653
1654 int amount_used = 1;
1655 if( target.type->has_use() ) {
1656 amount_used = target.type->invoke( *this->as_player(), target, pos() );
1657 if( amount_used <= 0 ) {
1658 return false;
1659 }
1660 }
1661
1662 // TODO: Get the target it was used on
1663 // Otherwise injecting someone will give us addictions etc.
1664 if( target.has_flag( "NO_INGEST" ) ) {
1665 const auto &comest = *target.get_comestible();
1666 // Assume that parenteral meds don't spoil, so don't apply rot
1667 modify_health( comest );
1668 modify_stimulation( comest );
1669 modify_fatigue( comest );
1670 modify_radiation( comest );
1671 modify_addiction( comest );
1672 modify_morale( target );
1673 } else {
1674 // Take by mouth
1675 consume_effects( target );
1676 }
1677
1678 mod_moves( -250 );
1679 target.charges -= amount_used;
1680 return target.charges <= 0;
1681}
bool consume_effects(item &food)
Handles the effects of consuming an item.
static const bionic_id bio_syringe("bio_syringe")
static const itype_id itype_syringe("syringe")
cata::value_ptr< islot_tool > tool
Definition: itype.h:849
bool has_use() const
Definition: itype.cpp:66
int invoke(player &p, item &it, const tripoint &pos) const
Definition: itype.cpp:105
std::string nname(unsigned int quantity) const
Definition: itype.cpp:46

References _, Creature::add_msg_if_player(), Creature::as_player(), bio_syringe, item::charges, consume_effects(), item::get_comestible(), visitable< Character >::has_amount(), has_bionic(), has_charges(), item::has_flag(), itype::has_use(), itype::invoke(), item::is_medication(), itype_syringe, m_info, Creature::mod_moves(), modify_addiction(), modify_fatigue(), modify_health(), modify_morale(), modify_radiation(), modify_stimulation(), itype::nname(), pos(), itype::tool, item::type, and use_charges().

Referenced by consume_item().

◆ consume_remote_fuel()

int Character::consume_remote_fuel ( int  amount)

Consume fuel used by remote powered bionic, return amount of request unfulfilled (0 if totally successful).

Definition at line 1409 of file bionics.cpp.

1410{
1411 int unconsumed_amount = amount;
1412 const std::vector<item *> cables = items_with( []( const item & it ) {
1413 return it.active && it.has_flag( flag_CABLE_SPOOL );
1414 } );
1415
1416 map &here = get_map();
1417 for( const item *cable : cables ) {
1418 const cata::optional<tripoint> target = cable->get_cable_target( this, pos() );
1419 if( target ) {
1420 const optional_vpart_position vp = here.veh_at( *target );
1421 if( !vp ) {
1422 continue;
1423 }
1424 unconsumed_amount = vp->vehicle().discharge_battery( amount );
1425 }
1426 }
1427
1428 if( unconsumed_amount > 0 ) {
1429 static const item_filter used_ups = [&]( const item & itm ) {
1430 return itm.get_var( "cable" ) == "plugged_in";
1431 };
1432 if( has_charges( itype_UPS_off, unconsumed_amount, used_ups ) ) {
1433 use_charges( itype_UPS_off, unconsumed_amount, used_ups );
1434 unconsumed_amount -= 1;
1435 } else if( has_charges( itype_adv_UPS_off, unconsumed_amount, used_ups ) ) {
1436 use_charges( itype_adv_UPS_off, roll_remainder( unconsumed_amount * 0.6 ), used_ups );
1437 unconsumed_amount -= 1;
1438 }
1439 }
1440
1441 return unconsumed_amount;
1442}
static const itype_id itype_adv_UPS_off("adv_UPS_off")
static const itype_id itype_UPS_off("UPS_off")
std::function< bool(const item &)> item_filter
Definition: game.h:119

References item::active, flag_CABLE_SPOOL(), get_map(), has_charges(), item::has_flag(), visitable< Character >::items_with(), itype_adv_UPS_off, itype_UPS_off, pos(), roll_remainder(), and use_charges().

Referenced by burn_fuel().

◆ cough()

void Character::cough ( bool  harmful = false,
int  loudness = 4 
)

Definition at line 7507 of file character.cpp.

7508{
7510 return;
7511 }
7512
7513 if( harmful ) {
7514 const int stam = get_stamina();
7515 const int malus = get_stamina_max() * 0.05; // 5% max stamina
7516 mod_stamina( -malus );
7517 if( stam < malus && x_in_y( malus - stam, malus ) && one_in( 6 ) ) {
7518 apply_damage( nullptr, bodypart_id( "torso" ), 1 );
7519 }
7520 }
7521
7522 if( !is_npc() ) {
7523 add_msg( m_bad, _( "You cough heavily." ) );
7524 }
7525 sounds::sound( pos(), loudness, sounds::sound_t::speech, _( "a hacking cough." ), false, "misc",
7526 "cough" );
7527
7528 moves -= 80;
7529
7530 add_effect( effect_recently_coughed, 5_minutes );
7531}
static const efftype_id effect_cough_suppress("cough_suppress")
static const efftype_id effect_recently_coughed("recently_coughed")

References _, Creature::add_effect(), add_msg(), apply_damage(), effect_cough_suppress, effect_recently_coughed, get_stamina(), get_stamina_max(), Creature::has_effect(), Creature::is_npc(), m_bad, mod_stamina(), Creature::moves, one_in(), pos(), sounds::sound(), sounds::speech, and x_in_y().

Referenced by eff_fun_fungus(), and process_one_effect().

◆ covered_with_flag()

bool Character::covered_with_flag ( const std::string &  flag,
const body_part_set parts 
) const

Definition at line 8928 of file character.cpp.

8929{
8930 if( parts.none() ) {
8931 return true;
8932 }
8933
8934 body_part_set to_cover( parts );
8935
8936 for( const auto &elem : worn ) {
8937 if( !elem.has_flag( flag ) ) {
8938 continue;
8939 }
8940
8941 to_cover &= ~elem.get_covered_body_parts();
8942
8943 if( to_cover.none() ) {
8944 return true; // Allows early exit.
8945 }
8946 }
8947
8948 return to_cover.none();
8949}
bool none() const
Definition: bodypart.h:249

References body_part_set::none(), and worn.

Referenced by is_waterproof().

◆ crafting_inventory() [1/2]

const inventory & Character::crafting_inventory ( bool  clear_path)

Definition at line 554 of file crafting.cpp.

555{
556 return crafting_inventory( tripoint_zero, PICKUP_RANGE, clear_path );
557}
const inventory & crafting_inventory(bool clear_path)
Definition: crafting.cpp:554

References crafting_inventory(), PICKUP_RANGE, and tripoint_zero.

Referenced by iexamine::autodoc(), autodoc_internal(), game::butcher(), activity_handlers::butcher_finish(), butcher_submenu(), can_butcher_at(), player::can_continue_craft(), can_do_activity_there(), player::can_make(), player::can_start_craft(), complete_craft(), veh_interact::complete_vehicle(), consider_butchery(), construction_color(), activity_handlers::cracking_do_turn(), iuse::craft(), crafting_inventory(), iexamine::cvdmachine(), iuse::dig(), game_menus::inv::disassemble(), item::final_info(), wash_activity_actor::finish(), bionic_install_preset::get_failure_chance(), repair_item_actor::handle_components(), has_enough_anesth(), list_available_constructions(), avatar_funcs::mend_item(), activity_handlers::mend_item_finish(), mill_load_food(), modify_morale(), veh_utils::most_repairable_part(), iexamine::nanofab(), iexamine::pit(), prompt_disassemble_in_seq(), examine_item_menu::rate_action_disassemble(), veh_utils::repair_part(), iexamine::safe(), deduped_requirement_data::select_alternative(), select_crafting_recipe(), iexamine::sign(), smoker_load_food(), iexamine::tree_maple(), disassemble_activity_actor::try_start_single(), sew_advanced_actor::use(), and wash_items().

◆ crafting_inventory() [2/2]

const inventory & Character::crafting_inventory ( const tripoint src_pos = tripoint_zero,
int  radius = PICKUP_RANGE,
bool  clear_path = true 
)

Definition at line 559 of file crafting.cpp.

561{
562 tripoint inv_pos = src_pos;
563 if( src_pos == tripoint_zero ) {
564 inv_pos = pos();
565 }
566 if( cached_moves == moves
568 && cached_position == inv_pos ) {
570 }
571 cached_crafting_inventory.form_from_map( inv_pos, radius, this, false, clear_path );
575 for( const bionic &bio : *my_bionics ) {
576 const bionic_data &bio_data = bio.info();
577 if( ( !bio_data.activated || bio.powered ) &&
578 !bio_data.fake_item.is_empty() ) {
579 cached_crafting_inventory += item( bio.info().fake_item,
581 }
582 }
583 if( has_trait( trait_BURROW ) ) {
586 }
587
590 cached_position = inv_pos;
591 // cache the qualities of the items in cached_crafting_inventory
594}
tripoint cached_position
Definition: character.h:2241
int cached_moves
Definition: character.h:2240
inventory cached_crafting_inventory
Definition: character.h:2242
void form_from_map(const tripoint &origin, int range, const Character *pl=nullptr, bool assign_invlet=true, bool clear_path=true)
Definition: inventory.cpp:473
void update_quality_cache()
Definition: inventory.cpp:1117
static const trait_id trait_BURROW("BURROW")
bool activated
Is true if a bionic is an active instead of a passive bionic.
Definition: bionics.h:51

References bionic_data::activated, cached_crafting_inventory, cached_moves, cached_position, cached_time, bionic_data::fake_item, inventory::form_from_map(), get_power_level(), has_trait(), inv, string_id< T >::is_empty(), Creature::moves, my_bionics, pos(), units::to_kilojoule(), trait_BURROW, tripoint_zero, calendar::turn, inventory::update_quality_cache(), weapon, and worn.

◆ crit_chance()

double Character::crit_chance ( float  roll_hit,
float  target_dodge,
const item weap 
) const

Returns the chance to critical given a hit roll and target's dodge roll.

Unarmed increases critical chance with UNARMED_WEAPON Dexterity increases chance for critical hits Perception increases chance for critical hits Bashing increases critical chance with bashing weapons Cutting increases critical chance with cutting weapons Stabbing increases critical chance with piercing weapons Unarmed increases critical chance with unarmed weapons Melee slightly increases critical chance with any item

Definition at line 739 of file melee.cpp.

740{
741 // Weapon to-hit roll
742 double weapon_crit_chance = 0.5;
743 if( weap.is_unarmed_weapon() ) {
744 // Unarmed attack: 1/2 of unarmed skill is to-hit
745 /** @EFFECT_UNARMED increases critical chance with UNARMED_WEAPON */
746 weapon_crit_chance = 0.5 + 0.05 * get_skill_level( skill_unarmed );
747 }
748
749 if( weap.type->m_to_hit > 0 ) {
750 weapon_crit_chance = std::max( weapon_crit_chance, 0.5 + 0.1 * weap.type->m_to_hit );
751 } else if( weap.type->m_to_hit < 0 ) {
752 weapon_crit_chance += 0.1 * weap.type->m_to_hit;
753 }
754 weapon_crit_chance = limit_probability( weapon_crit_chance );
755
756 // Dexterity and perception
757 /** @EFFECT_DEX increases chance for critical hits */
758
759 /** @EFFECT_PER increases chance for critical hits */
760 const double stat_crit_chance = limit_probability( 0.25 + 0.01 * dex_cur + ( 0.02 * per_cur ) );
761
762 /** @EFFECT_BASHING increases critical chance with bashing weapons */
763 /** @EFFECT_CUTTING increases critical chance with cutting weapons */
764 /** @EFFECT_STABBING increases critical chance with piercing weapons */
765 /** @EFFECT_UNARMED increases critical chance with unarmed weapons */
766 int sk = get_skill_level( weap.melee_skill() );
767 if( has_active_bionic( bio_cqb ) ) {
768 sk = std::max( sk, BIO_CQB_LEVEL );
769 }
770
771 /** @EFFECT_MELEE slightly increases critical chance with any item */
772 sk += get_skill_level( skill_melee ) / 2.5;
773
774 const double skill_crit_chance = limit_probability( 0.25 + sk * 0.025 );
775
776 // Examples (survivor stats/chances of each critical):
777 // Fresh (skill-less) 8/8/8/8, unarmed:
778 // 50%, 49%, 25%; ~1/16 guaranteed critical + ~1/8 if roll>dodge*1.5
779 // Expert (skills 10) 10/10/10/10, unarmed:
780 // 100%, 55%, 60%; ~1/3 guaranteed critical + ~4/10 if roll>dodge*1.5
781 // Godlike with combat CBM 20/20/20/20, pipe (+1 accuracy):
782 // 60%, 100%, 42%; ~1/4 guaranteed critical + ~3/8 if roll>dodge*1.5
783
784 // Note: the formulas below are only valid if none of the 3 critical chance values go above 1.0
785 // It is therefore important to limit them to between 0.0 and 1.0
786
787 // Chance to get all 3 criticals (a guaranteed critical regardless of hit/dodge)
788 const double chance_triple = weapon_crit_chance * stat_crit_chance * skill_crit_chance;
789 // Only check double critical (one that requires hit/dodge comparison) if we have good
790 // hit vs dodge
791 if( roll_hit > target_dodge * 3 / 2 ) {
792 const double chance_double = 0.5 * (
793 weapon_crit_chance * stat_crit_chance +
794 stat_crit_chance * skill_crit_chance +
795 weapon_crit_chance * skill_crit_chance -
796 ( 3 * chance_triple ) );
797 // Because chance_double already removed the triples with -( 3 * chance_triple ),
798 // chance_triple and chance_double are mutually exclusive probabilities and can just
799 // be added together.
801 melee::melee_stats.double_crit_chance += chance_double + chance_triple;
802 return chance_triple + chance_double;
803 }
805 melee::melee_stats.crit_chance += chance_triple;
806 return chance_triple;
807}
bool is_unarmed_weapon() const
Definition: item.cpp:738
skill_id melee_skill() const
The most relevant skill used with this melee weapon.
Definition: item.cpp:7208
double limit_probability(double unbounded_probability)
Limits a probability to be between 0.0 and 1.0.
Definition: melee.cpp:734
melee_statistic_data melee_stats
Definition: melee.cpp:2459
int m_to_hit
Definition: itype.h:1000
double crit_chance
Definition: melee.h:15
int double_crit_count
Definition: melee.h:11
double double_crit_chance
Definition: melee.h:14

References bio_cqb, BIO_CQB_LEVEL, melee_statistic_data::crit_chance, melee_statistic_data::crit_count, dex_cur, melee_statistic_data::double_crit_chance, melee_statistic_data::double_crit_count, get_skill_level(), has_active_bionic(), item::is_unarmed_weapon(), limit_probability(), itype::m_to_hit, item::melee_skill(), melee::melee_stats, per_cur, skill_melee, skill_unarmed, and item::type.

Referenced by item::combat_info(), item::effective_dps(), and scored_crit().

◆ crossed_threshold()

bool Character::crossed_threshold ( ) const

Returns true if the player has crossed a mutation threshold Player can only cross one mutation threshold.

Definition at line 8672 of file character.cpp.

8673{
8674 for( const trait_id &mut : get_mutations() ) {
8675 if( mut->threshold ) {
8676 return true;
8677 }
8678 }
8679 return false;
8680}

References get_mutations(), and mutation_branch::threshold.

Referenced by character_display::disp_info(), draw_tip(), hardcoded_effects(), marloss_common(), modify_morale(), conditional_t< T >::set_has_trait_flag(), and test_crossing_threshold().

◆ deactivate_bionic()

bool Character::deactivate_bionic ( bionic bio,
bool  eff_only = false 
)

Handles bionic deactivation effects of the entered bionic, returns if anything deactivated.

Definition at line 1065 of file bionics.cpp.

1066{
1067 if( bio.incapacitated_time > 0_turns ) {
1068 add_msg_if_player( m_info, _( "Your %s is shorting out and can't be deactivated." ),
1069 bio.info().name );
1070 return false;
1071 }
1072
1073 if( bio.info().is_remote_fueled ) {
1075 }
1076
1077 // Just do the effect, no stat changing or messages
1078 if( !eff_only ) {
1079 if( !bio.powered ) {
1080 // It's already off!
1081 return false;
1082 }
1083 if( !bio.info().has_flag( flag_BIONIC_TOGGLED ) ) {
1084 // It's a fire-and-forget bionic, we can't turn it off but have to wait for
1085 //it to run out of charge
1086 add_msg_if_player( m_info, _( "You can't deactivate your %s manually!" ),
1087 bio.info().name );
1088 return false;
1089 }
1090 if( get_power_level() < bio.info().power_deactivate ) {
1091 add_msg_if_player( m_info, _( "You don't have the power to deactivate your %s." ),
1092 bio.info().name );
1093 return false;
1094 }
1095
1096 //We can actually deactivate now, do deactivation-y things
1098 bio.powered = false;
1099 add_msg_if_player( m_neutral, _( "You deactivate your %s." ), bio.info().name );
1100 }
1101
1102 // Deactivation effects go here
1103 if( bio.info().has_flag( flag_BIONIC_WEAPON ) ) {
1104 if( weapon.typeId() == bio.info().fake_item ) {
1105 add_msg_if_player( _( "You withdraw your %s." ), weapon.tname() );
1106 if( g->u.sees( pos() ) ) {
1107 add_msg_if_npc( m_info, _( "<npcname> withdraws %s %s." ), disp_name( true ),
1108 weapon.tname() );
1109 }
1110 bio.ammo_loaded =
1111 weapon.ammo_data() != nullptr ? weapon.ammo_data()->get_id() : itype_id::NULL_ID();
1112 bio.ammo_count = static_cast<unsigned int>( weapon.ammo_remaining() );
1113 weapon = item();
1115 }
1116 } else if( bio.id == bio_cqb ) {
1117 martial_arts_data->selected_style_check();
1118 } else if( bio.id == bio_remote ) {
1119 if( g->remoteveh() != nullptr && !has_active_item( itype_remotevehcontrol ) ) {
1120 g->setremoteveh( nullptr );
1121 } else if( !get_value( "remote_controlling" ).empty() &&
1123 set_value( "remote_controlling", "" );
1124 }
1125 } else if( bio.id == bio_tools ) {
1127 } else if( bio.id == bio_ads ) {
1129 bio.energy_stored = 0_kJ;
1130 }
1131
1132 // Recalculate stats (strength, mods from pain etc.) that could have been affected
1134 reset();
1135 if( !bio.id->enchantments.empty() ) {
1137 }
1138
1139 // Also reset crafting inventory cache if this bionic spawned a fake item
1140 if( !bio.info().fake_item.is_empty() ) {
1142 }
1143
1144 // Compatibility with old saves without the toolset hammerspace
1145 if( !eff_only && bio.id == bio_tools && !has_bionic( bionic_TOOLS_EXTEND ) ) {
1146 // E X T E N D T O O L S
1148 }
1149
1150 return true;
1151}
static const bionic_id bio_ads("bio_ads")
static const itype_id itype_remotevehcontrol("remotevehcontrol")
static const bionic_id bionic_TOOLS_EXTEND("bio_tools_extend")
static const itype_id itype_radiocontrol("radiocontrol")
bool has_active_item(const itype_id &id) const
Whether the player carries an active item of the given item type.
Definition: character.cpp:2479
void reset_remote_fuel()
Definition: bionics.cpp:1444
virtual void add_msg_if_npc(const std::string &) const
Definition: creature.h:639
const itype * ammo_data() const
Specific ammo data, returns nullptr if item is neither ammo nor loaded with any.
Definition: item.cpp:7538
static const string_id< itype > & NULL_ID()
Returns a null id whose string_id<T>::is_null() must always return true.
units::energy power_deactivate
Power cost on deactivation.
Definition: bionics.h:39

References _, add_bionic(), Creature::add_msg_if_npc(), Creature::add_msg_if_player(), bionic::ammo_count, item::ammo_data(), bionic::ammo_loaded, item::ammo_remaining(), bio_ads, bio_cqb, bio_remote, bio_tools, bionic_TOOLS_EXTEND, disp_name(), bionic_data::enchantments, bionic::energy_stored, bionic_data::fake_item, flag_BIONIC_TOGGLED, flag_BIONIC_WEAPON, g, itype::get_id(), get_power_level(), Creature::get_value(), has_active_item(), has_bionic(), bionic_data::has_flag(), bionic::id, bionic::incapacitated_time, bionic::info(), invalidate_crafting_inventory(), string_id< T >::is_empty(), bionic_data::is_remote_fueled, itype_radiocontrol, itype_remotevehcontrol, m_info, m_neutral, martial_arts_data, mod_power_level(), bionic_data::name, string_id< itype >::NULL_ID(), pos(), bionic_data::power_deactivate, bionic::powered, recalculate_enchantment_cache(), reset(), reset_encumbrance(), reset_remote_fuel(), Creature::set_value(), item::tname(), item::typeId(), and weapon.

Referenced by absorb_hit(), burn_fuel(), npc::deactivate_bionic_by_id(), process_bionic(), show_bionics_ui(), and uninstall_bionic().

◆ deactivate_mutation()

void Character::deactivate_mutation ( const trait_id mut)

Definition at line 610 of file mutation.cpp.

611{
612 my_mutations[mut].powered = false;
613
614 // Handle stat changes from deactivation
615 apply_mods( mut, false );
617 const mutation_branch &mdata = mut.obj();
618 if( mdata.transform ) {
619 const cata::value_ptr<mut_transform> trans = mdata.transform;
620 mod_moves( -trans->moves );
621 switch_mutations( mut, trans->target, trans->active );
622 }
623
624 if( !mut->enchantments.empty() ) {
626 }
627}
void apply_mods(const trait_id &mut, bool add_remove)
Applies stat mods to character.
Definition: mutation.cpp:206
std::vector< enchantment_id > enchantments
mutation enchantments
Definition: mutation.h:236

References apply_mods(), mutation_branch::enchantments, Creature::mod_moves(), my_mutations, string_id< T >::obj(), recalc_sight_limits(), recalculate_enchantment_cache(), switch_mutations(), and mutation_branch::transform.

Referenced by show_mutations_ui(), and detail::show_mutations_ui_internal().

◆ deal_damage()

dealt_damage_instance Character::deal_damage ( Creature source,
bodypart_id  bp,
const damage_instance d 
)
overridevirtual

Calls Creature::deal_damage and handles damaged effects (waking up, etc.)

Dexterity increases chance to avoid being grabbed

Reimplemented from Creature.

Definition at line 8419 of file character.cpp.

8421{
8422 if( has_trait( trait_DEBUG_NODMG ) ) {
8423 return dealt_damage_instance();
8424 }
8425
8426 const body_part bp_token = bp->token;
8427 if( bp_token == num_bp ) {
8428 debugmsg( "Wacky bodypart hit!" );
8429 return dealt_damage_instance();
8430 }
8431
8432 //damage applied here
8433 dealt_damage_instance dealt_dams = Creature::deal_damage( source, bp, d );
8434 //block reduction should be by applied this point
8435 int dam = dealt_dams.total_damage();
8436
8437 // TODO: Pre or post blit hit tile onto "this"'s location here
8438 if( dam > 0 && g->u.sees( pos() ) ) {
8439 g->draw_hit_player( *this, dam );
8440
8441 if( is_player() && source ) {
8442 //monster hits player melee
8443 SCT.add( point( posx(), posy() ),
8444 direction_from( point_zero, point( posx() - source->posx(), posy() - source->posy() ) ),
8445 get_hp_bar( dam, get_hp_max( bp ) ).first, m_bad, body_part_name( bp ), m_neutral );
8446 }
8447 }
8448
8449 // handle snake artifacts
8450 if( has_artifact_with( AEP_SNAKES ) && dam >= 6 ) {
8451 const int snakes = dam / 6;
8452 int spawned = 0;
8453 for( int i = 0; i < snakes; i++ ) {
8454 if( monster *const snake = g->place_critter_around( mon_shadow_snake, pos(), 1 ) ) {
8455 snake->friendly = -1;
8456 spawned++;
8457 }
8458 }
8459 if( spawned == 1 ) {
8460 add_msg( m_warning, _( "A snake sprouts from your body!" ) );
8461 } else if( spawned >= 2 ) {
8462 add_msg( m_warning, _( "Some snakes sprout from your body!" ) );
8463 }
8464 }
8465
8466 // And slimespawners too
8467 if( ( has_trait( trait_SLIMESPAWNER ) ) && ( dam >= 10 ) && one_in( 20 - dam ) ) {
8468 if( monster *const slime = g->place_critter_around( mon_player_blob, pos(), 1 ) ) {
8469 slime->friendly = -1;
8470 add_msg_if_player( m_warning, _( "Slime is torn from you, and moves on its own!" ) );
8471 }
8472 }
8473
8474 //Acid blood effects.
8475 bool u_see = g->u.sees( *this );
8476 int cut_dam = dealt_dams.type_damage( DT_CUT );
8477 if( source && has_trait( trait_ACIDBLOOD ) && !one_in( 3 ) &&
8478 ( dam >= 4 || cut_dam > 0 ) && ( rl_dist( g->u.pos(), source->pos() ) <= 1 ) ) {
8479 if( is_player() ) {
8480 add_msg( m_good, _( "Your acidic blood splashes %s in mid-attack!" ),
8481 source->disp_name() );
8482 } else if( u_see ) {
8483 add_msg( _( "%1$s's acidic blood splashes on %2$s in mid-attack!" ),
8484 disp_name(), source->disp_name() );
8485 }
8486 damage_instance acidblood_damage;
8487 acidblood_damage.add_damage( DT_ACID, rng( 4, 16 ) );
8488 if( !one_in( 4 ) ) {
8489 source->deal_damage( this, bodypart_id( "arm_l" ), acidblood_damage );
8490 source->deal_damage( this, bodypart_id( "arm_r" ), acidblood_damage );
8491 } else {
8492 source->deal_damage( this, bodypart_id( "torso" ), acidblood_damage );
8493 source->deal_damage( this, bodypart_id( "head" ), acidblood_damage );
8494 }
8495 }
8496
8497 int recoil_mul = 100;
8498
8499 if( bp == bodypart_id( "eyes" ) ) {
8500 if( dam > 5 || cut_dam > 0 ) {
8501 const time_duration minblind = std::max( 1_turns, 1_turns * ( dam + cut_dam ) / 10 );
8502 const time_duration maxblind = std::min( 5_turns, 1_turns * ( dam + cut_dam ) / 4 );
8503 add_effect( effect_blind, rng( minblind, maxblind ) );
8504 }
8505 } else if( bp == bodypart_id( "hand_l" ) || bp == bodypart_id( "arm_l" ) ||
8506 bp == bodypart_id( "hand_r" ) || bp == bodypart_id( "arm_r" ) ) {
8507 recoil_mul = 200;
8508 } else if( bp == bodypart_id( "num_bp" ) ) {
8509 debugmsg( "Wacky body part hit!" );
8510 }
8511
8512
8513
8514 // TODO: Scale with damage in a way that makes sense for power armors, plate armor and naked skin.
8515 recoil += recoil_mul * weapon.volume() / 250_ml;
8516 recoil = std::min( MAX_RECOIL, recoil );
8517 //looks like this should be based off of dealt damages, not d as d has no damage reduction applied.
8518 // Skip all this if the damage isn't from a creature. e.g. an explosion.
8519 if( source != nullptr ) {
8520 if( source->has_flag( MF_GRABS ) && !source->is_hallucination() &&
8521 !source->has_effect( effect_grabbing ) ) {
8522 /** @EFFECT_DEX increases chance to avoid being grabbed */
8523
8524 if( has_grab_break_tec() && ( rng( 0, get_dex() ) > rng( 0, 10 ) ) ) {
8525 if( has_effect( effect_grabbed ) ) {
8526 add_msg_if_player( m_warning, _( "The %s tries to grab you as well, but you bat it away!" ),
8527 source->disp_name() );
8528 } else {
8529 add_msg_player_or_npc( m_info, _( "The %s tries to grab you, but you break its grab!" ),
8530 _( "The %s tries to grab <npcname>, but they break its grab!" ),
8531 source->disp_name() );
8532 }
8533 } else {
8534 int prev_effect = get_effect_int( effect_grabbed );
8535 add_effect( effect_grabbed, 2_turns, bp_torso, prev_effect + 2 );
8536 source->add_effect( effect_grabbing, 2_turns );
8537 add_msg_player_or_npc( m_bad, _( "You are grabbed by %s!" ), _( "<npcname> is grabbed by %s!" ),
8538 source->disp_name() );
8539 }
8540 }
8541 }
8542
8543 if( get_option<bool>( "FILTHY_WOUNDS" ) ) {
8544 int sum_cover = 0;
8545 for( const item &i : worn ) {
8546 if( i.covers( bp->token ) && i.is_filthy() ) {
8547 sum_cover += i.get_coverage();
8548 }
8549 }
8550
8551 // Chance of infection is damage (with cut and stab x4) * sum of coverage on affected body part, in percent.
8552 // i.e. if the body part has a sum of 100 coverage from filthy clothing,
8553 // each point of damage has a 1% change of causing infection.
8554 if( sum_cover > 0 ) {
8555 const int cut_type_dam = dealt_dams.type_damage( DT_CUT ) + dealt_dams.type_damage( DT_STAB );
8556 const int combined_dam = dealt_dams.type_damage( DT_BASH ) + ( cut_type_dam * 4 );
8557 const int infection_chance = ( combined_dam * sum_cover ) / 100;
8558 if( x_in_y( infection_chance, 100 ) ) {
8559 if( has_effect( effect_bite, bp->token ) ) {
8560 add_effect( effect_bite, 40_minutes, bp->token );
8561 } else if( has_effect( effect_infected, bp->token ) ) {
8562 add_effect( effect_infected, 25_minutes, bp->token );
8563 } else {
8564 add_effect( effect_bite, 1_turns, bp->token );
8565 }
8566 add_msg_if_player( _( "Filth from your clothing has implanted deep in the wound." ) );
8567 }
8568 }
8569 }
8570
8571 on_hurt( source );
8572 return dealt_dams;
8573}
static const efftype_id effect_blind("blind")
static const trait_id trait_SLIMESPAWNER("SLIMESPAWNER")
static const mtype_id mon_player_blob("mon_player_blob")
static const efftype_id effect_grabbing("grabbing")
static const mtype_id mon_shadow_snake("mon_shadow_snake")
static const efftype_id effect_grabbed("grabbed")
double recoil
Definition: character.h:563
virtual int posy() const =0
virtual std::string disp_name(bool possessive=false, bool capitalize_first=false) const =0
virtual const tripoint & pos() const =0
virtual dealt_damage_instance deal_damage(Creature *source, bodypart_id bp, const damage_instance &dam)
Deals the damage via an attack.
Definition: creature.cpp:880
virtual bool has_flag(const m_flag) const
Definition: creature.h:486
virtual int get_hp_max() const
Definition: creature.cpp:1675
virtual int posx() const =0
units::volume volume(bool integral=false) const
Total volume of an item accounting for all contained/integrated items NOTE: Result is rounded up to n...
Definition: item.cpp:5093
direction direction_from(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:540
@ AEP_SNAKES
Definition: enums.h:109
constexpr double MAX_RECOIL
@ MF_GRABS
Definition: mtype.h:76
bool snake(const tripoint &p, Creature *c, item *i)
Definition: trapfunc.cpp:1428
static constexpr point point_zero
Definition: point.h:274
void add_damage(damage_type dt, float amt, float arpen=0.0f, float arpen_mult=1.0f, float dmg_mult=1.0f)
Adds damage to the instance.
Definition: damage.cpp:41
int type_damage(damage_type dt) const
Definition: damage.cpp:172
int total_damage() const
Definition: damage.cpp:180

References _, scrollingcombattext::add(), damage_instance::add_damage(), Creature::add_effect(), add_msg(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), AEP_SNAKES, body_part_name(), bp_torso, Creature::deal_damage(), debugmsg, direction_from(), Creature::disp_name(), disp_name(), DT_ACID, DT_BASH, DT_CUT, DT_STAB, effect_bite, effect_blind, effect_grabbed, effect_grabbing, effect_infected, g, get_dex(), Creature::get_effect_int(), get_hp_bar(), Creature::get_hp_max(), has_artifact_with(), Creature::has_effect(), Creature::has_flag(), has_grab_break_tec(), has_trait(), Creature::is_hallucination(), Creature::is_player(), m_bad, m_good, m_info, m_neutral, m_warning, MAX_RECOIL, MF_GRABS, mon_player_blob, mon_shadow_snake, num_bp, on_hurt(), one_in(), point_zero, Creature::pos(), pos(), Creature::posx(), posx(), Creature::posy(), posy(), recoil, rl_dist(), rng(), SCT, trapfunc::snake(), dealt_damage_instance::total_damage(), trait_ACIDBLOOD, trait_DEBUG_NODMG, trait_SLIMESPAWNER, dealt_damage_instance::type_damage(), item::volume(), weapon, worn, and x_in_y().

Referenced by mattack::bio_op_impale(), mattack::bio_op_takedown(), map::burn_body_part(), map::crush(), trapfunc::dissector(), explosion_handler::do_blast(), map::drop_furniture(), eff_fun_onfire(), trapfunc::goo(), hitall(), impact(), knock_back_to(), game::knockback(), trapfunc::lava(), melee_special_effects(), petfood(), trapfunc::pit(), trapfunc::pit_glass(), trapfunc::pit_spikes(), game::place_player(), map::player_in_field(), smash(), trapfunc::snare_heavy(), and mattack::thrown_by_judo().

◆ defer_move()

bool Character::defer_move ( const tripoint next)

Definition at line 10521 of file character.cpp.

10522{
10523 // next must be adjacent to current pos
10524 if( square_dist( next, pos() ) != 1 ) {
10525 return false;
10526 }
10527 // next must be adjacent to subsequent move in any preexisting automove route
10528 if( has_destination() && square_dist( auto_move_route.front(), next ) != 1 ) {
10529 return false;
10530 }
10531 auto_move_route.insert( auto_move_route.begin(), next );
10533 return true;
10534}
bool has_destination() const
int square_dist(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:505

References auto_move_route, has_destination(), next_expected_position, pos(), and square_dist().

Referenced by avatar_action::move().

◆ did_hit()

void Character::did_hit ( Creature target)

Handles special effects when the Character hits a Creature.

Definition at line 8247 of file character.cpp.

8248{
8249 enchantment_cache->cast_hit_you( *this, target );
8250}

References enchantment_cache.

Referenced by melee_attack().

◆ die()

void Character::die ( Creature killer)
overridevirtual

Empty function.

Should always be overwritten by the appropriate player/NPC/monster version.

Implements Creature.

Reimplemented in npc.

Definition at line 3514 of file character.cpp.

3515{
3516 g->set_critter_died();
3517 set_killer( nkiller );
3519 if( has_effect( effect_lightsnare ) ) {
3522 }
3523 if( has_effect( effect_heavysnare ) ) {
3526 }
3527 if( has_effect( effect_beartrap ) ) {
3529 }
3531}
static const itype_id itype_string_36("string_36")
static const efftype_id effect_lightsnare("lightsnare")
static const itype_id itype_snare_trigger("snare_trigger")
static const itype_id itype_beartrap("beartrap")
static const efftype_id effect_beartrap("beartrap")
static const efftype_id effect_heavysnare("heavysnare")
static const itype_id itype_rope_6("rope_6")
void set_time_died(const time_point &time)
set the turn the turn the character died if not already done
Definition: character.h:1442
static void on_creature_death(Creature &poor_dead_dude)
various callbacks from events that may affect all missions
Definition: mission.cpp:132

References inventory::add_item(), effect_beartrap, effect_heavysnare, effect_lightsnare, g, Creature::has_effect(), inv, itype_beartrap, itype_rope_6, itype_snare_trigger, itype_string_36, mission::on_creature_death(), Creature::set_killer(), set_time_died(), calendar::start_of_cataclysm, and calendar::turn.

Referenced by debug_menu::debug(), and npc::die().

◆ dismount()

void Character::dismount ( )

Definition at line 1168 of file character.cpp.

1169{
1170 if( !is_mounted() ) {
1171 add_msg( m_debug, "dismount called when not riding" );
1172 return;
1173 }
1174 if( const cata::optional<tripoint> pnt = choose_adjacent( _( "Dismount where?" ) ) ) {
1175 if( !g->is_empty( *pnt ) ) {
1176 add_msg( m_warning, _( "You cannot dismount there!" ) );
1177 return;
1178 }
1180 monster *critter = mounted_creature.get();
1181 critter->mounted_player_id = character_id();
1182 if( critter->has_flag( MF_RIDEABLE_MECH ) && !critter->type->mech_weapon.is_empty() &&
1183 weapon.typeId() == critter->type->mech_weapon ) {
1185 }
1186 if( is_avatar() && g->u.get_grab_type() != OBJECT_NONE ) {
1187 add_msg( m_warning, _( "You let go of the grabbed object." ) );
1188 g->u.grab( OBJECT_NONE );
1189 }
1190 critter->remove_effect( effect_ridden );
1191 critter->add_effect( effect_ai_waiting, 5_turns );
1192 mounted_creature = nullptr;
1193 critter->mounted_player = nullptr;
1194 setpos( *pnt );
1195 mod_moves( -100 );
1197 }
1198}
static const efftype_id effect_ai_waiting("ai_waiting")
static const efftype_id effect_riding("riding")
static const efftype_id effect_ridden("ridden")
void setpos(const tripoint &p) override
Definition: character.h:804
virtual void set_movement_mode(character_movemode mode)=0
void add_effect(const efftype_id &eff_id, const time_duration &dur, const bodypart_str_id &bp, int intensity=0, bool force=false, bool deferred=false) override
Performs any monster-specific modifications to the arguments before passing to Creature::add_effect()...
Definition: monster.cpp:1840
Character * mounted_player
Definition: monster.h:457
character_id mounted_player_id
Definition: monster.h:458
item remove_item(item &it)
Removes and returns the item which must be contained by this instance.
Definition: visitable.cpp:563
@ OBJECT_NONE
Definition: enums.h:187

References _, monster::add_effect(), add_msg(), character_id, choose_adjacent(), CMM_WALK, effect_ai_waiting, effect_ridden, effect_riding, g, monster::has_flag(), Creature::is_avatar(), string_id< T >::is_empty(), is_mounted(), m_debug, m_warning, mtype::mech_weapon, MF_RIDEABLE_MECH, Creature::mod_moves(), mounted_creature, monster::mounted_player, monster::mounted_player_id, OBJECT_NONE, Creature::remove_effect(), visitable< Character >::remove_item(), set_movement_mode(), setpos(), monster::type, item::typeId(), and weapon.

Referenced by game::handle_action().

◆ disp_name()

std::string Character::disp_name ( bool  possessive = false,
bool  capitalize_first = false 
) const
overridevirtual

Returns either "you" or the player's name.

capitalize_first assumes that the character's name is already upper case and uses it only for possessive "your" and "you"

Implements Creature.

Definition at line 566 of file character.cpp.

567{
568 if( !possessive ) {
569 if( is_player() ) {
570 return capitalize_first ? _( "You" ) : _( "you" );
571 }
572 return name;
573 } else {
574 if( is_player() ) {
575 return capitalize_first ? _( "Your" ) : _( "your" );
576 }
577 return string_format( _( "%s's" ), name );
578 }
579}

References _, Creature::is_player(), name, and string_format().

Referenced by activity_on_turn_move_loot(), add_addiction(), iuse::artifact(), talk_function::assign_camp(), iexamine::autodoc(), best_installer(), bionics_install_failure(), activity_handlers::build_do_turn(), can_uninstall_bionic(), npc::character_danger(), game::chat(), check_and_recover_morale(), npc::check_or_use_weapon_cbm(), check_outbounds_activity(), complete_construction(), deactivate_bionic(), deal_damage(), faction_manager::display(), npc::do_npc_read(), npc::do_player_activity(), avatar::do_read(), npc::execute_action(), fetch_activity(), npc::finish_read(), talk_function::goto_location(), npc::handle_sound(), npc::heal_player(), npc::heal_self(), install_bionics(), game::list_missions(), npc::method_of_attack(), talk_function::morale_chat(), talk_function::morale_chat_activity(), npc::mutiny(), npc::npc_dismount(), game::npc_menu(), mattack::nurse_operate(), monster::nursebot_operate(), on_hit(), npc::on_load(), npc::pretend_fire(), npc::pretend_heal(), monster::print_info(), npc::reach_omt_destination(), avatar::read(), game_menus::inv::read(), requirements_map(), talk_effect_fun_t::set_consume_item(), npc::set_fac(), npc::set_known_to_u(), talk_function::start_camp(), character_funcs::try_uncanny_dodge(), uninstall_bionic(), trading_window::update_win(), musical_instrument_actor::use(), heal_actor::use_healing_item(), and npc::use_painkiller().

◆ dispose_item()

bool Character::dispose_item ( item_location &&  obj,
const std::string &  prompt = std::string() 
)
virtual

Drop, wear, stash or otherwise try to dispose of an item consuming appropriate moves.

Parameters
objitem to dispose of
promptoptional message to display in any menu
Returns
whether the item was successfully disposed of

Reimplemented in npc.

Definition at line 7225 of file character.cpp.

7226{
7227 uilist menu;
7228 menu.text = prompt.empty() ? string_format( _( "Dispose of %s" ), obj->tname() ) : prompt;
7229
7230 using dispose_option = struct {
7231 std::string prompt;
7232 bool enabled;
7233 char invlet;
7234 int moves;
7235 std::function<bool()> action;
7236 };
7237
7238 std::vector<dispose_option> opts;
7239
7240 const bool bucket = obj->is_bucket_nonempty();
7241
7242 opts.emplace_back( dispose_option{
7243 bucket ? _( "Spill contents and store in inventory" ) : _( "Store in inventory" ),
7244 volume_carried() + obj->volume() <= volume_capacity(), '1',
7245 item_handling_cost( *obj ),
7246 [this, bucket, &obj] {
7247 if( bucket && !obj->spill_contents( *this ) )
7248 {
7249 return false;
7250 }
7251
7252 moves -= item_handling_cost( *obj );
7253 inv.add_item_keep_invlet( *obj );
7254 inv.unsort();
7255 obj.remove_item();
7256 return true;
7257 }
7258 } );
7259
7260 opts.emplace_back( dispose_option{
7261 _( "Drop item" ), true, '2', 0, [this, &obj] {
7263 obj.remove_item();
7264 return true;
7265 }
7266 } );
7267
7268 opts.emplace_back( dispose_option{
7269 bucket ? _( "Spill contents and wear item" ) : _( "Wear item" ),
7270 can_wear( *obj ).success(), '3', item_wear_cost( *obj ),
7271 [this, bucket, &obj] {
7272 if( bucket && !obj->spill_contents( *this ) )
7273 {
7274 return false;
7275 }
7276
7277 item it = *obj;
7278 obj.remove_item();
7279 return !!wear_item( it );
7280 }
7281 } );
7282
7283 for( auto &e : worn ) {
7284 if( e.can_holster( *obj ) ) {
7285 auto ptr = dynamic_cast<const holster_actor *>( e.type->get_use( "holster" )->get_actor_ptr() );
7286 opts.emplace_back( dispose_option{
7287 string_format( _( "Store in %s" ), e.tname() ), true, e.invlet,
7288 item_store_cost( *obj, e, false, ptr->draw_cost ),
7289 [this, ptr, &e, &obj] {
7290 return ptr->store( *this->as_player(), e, *obj );
7291 }
7292 } );
7293 }
7294 }
7295
7296 int w = utf8_width( menu.text, true ) + 4;
7297 for( const auto &e : opts ) {
7298 w = std::max( w, utf8_width( e.prompt, true ) + 4 );
7299 }
7300 for( auto &e : opts ) {
7301 e.prompt += std::string( w - utf8_width( e.prompt, true ), ' ' );
7302 }
7303
7304 menu.text.insert( 0, 2, ' ' ); // add space for UI hotkeys
7305 menu.text += std::string( w + 2 - utf8_width( menu.text, true ), ' ' );
7306 menu.text += _( " | Moves " );
7307
7308 for( const auto &e : opts ) {
7309 menu.addentry( -1, e.enabled, e.invlet, string_format( e.enabled ? "%s | %-7d" : "%s |",
7310 e.prompt, e.moves ) );
7311 }
7312
7313 menu.query();
7314 if( menu.ret >= 0 ) {
7315 return opts[menu.ret].action();
7316 }
7317 return false;
7318}
cata::optional< std::list< item >::iterator > wear_item(const item &to_wear, bool interactive=true)
Wear a copy of specified item.
Definition: character.cpp:2100
int item_handling_cost(const item &it, bool penalties=true, int base_cost=INVENTORY_HANDLING_PENALTY) const
Calculate (but do not deduct) the number of moves required when handling (e.g.
Definition: character.cpp:7432
int item_wear_cost(const item &it) const
Calculate (but do not deduct) the number of moves required to wear an item.
Definition: character.cpp:7471
int item_store_cost(const item &it, const item &container, bool penalties=true, int base_cost=INVENTORY_HANDLING_PENALTY) const
Calculate (but do not deduct) the number of moves required when storing an item in a container.
Definition: character.cpp:7456
ret_val< bool > can_wear(const item &it, bool with_equip_change=false) const
Check character capable of wearing an item.
Definition: character.cpp:2730
Holster a weapon.
Definition: iuse_actor.h:843
void add_item_keep_invlet(item newit)
Definition: inventory.cpp:385
void remove_item()
Removes the selected item from the game.
bool spill_contents(Character &c)
Unloads the item's contents.
Definition: item.cpp:7059
bool is_bucket_nonempty() const
Definition: item.cpp:6750
const void * ptr(const T *p)
\rst Converts p to const void* for pointer formatting.
@ prompt
Definition: pickup.h:30

References _, action, inventory::add_item_keep_invlet(), uilist::addentry(), Creature::as_player(), can_wear(), deliberate, enabled, inv, item_handling_cost(), item_store_cost(), item_wear_cost(), Creature::moves, pickup::prompt, ptr(), put_into_vehicle_or_drop(), uilist::query(), visitable< T >::remove_item(), uilist::ret, string_format(), uilist::text, inventory::unsort(), utf8_width(), volume_capacity(), volume_carried(), wear_item(), and worn.

Referenced by activate_bionic(), item::reload(), and unwield().

◆ do_damage_for_bionic_failure()

void Character::do_damage_for_bionic_failure ( int  min_damage,
int  max_damage 
)

Definition at line 2347 of file bionics.cpp.

2348{
2349 std::set<bodypart_id> bp_hurt;
2350 for( const bodypart_id &bp : get_all_body_parts() ) {
2351 if( has_effect( effect_under_op, bp->token ) ) {
2352 if( bp_hurt.count( bp->main_part ) > 0 ) {
2353 continue;
2354 }
2355 bp_hurt.emplace( bp->main_part );
2356 }
2357 }
2358
2359 if( bp_hurt.empty() ) {
2360 // If no bodypart associetd with bionic- just damage torso.
2361 // Special check for power storage - it does not belong to any body part.
2362 bp_hurt.emplace( bodypart_str_id( "torso" ) );
2363 }
2364
2365 for( const bodypart_id &bp : bp_hurt ) {
2366 int damage = rng( min_damage, max_damage );
2367 int hp = get_hp( bp );
2368 if( damage >= hp && ( bp == bodypart_str_id( "head" ) || bp == bodypart_str_id( "torso" ) ) ) {
2369 add_effect( effect_infected, 1_hours, bp->token );
2370 add_msg_player_or_npc( m_bad, _( "Your %s is infected." ), _( "<npcname>'s %s is infected." ),
2372 damage = hp * 0.8f;
2373 }
2374 apply_damage( this, bp, damage, true );
2375 if( damage > 15 )
2376 add_msg_player_or_npc( m_bad, _( "Your %s is severely damaged." ),
2377 _( "<npcname>'s %s is severely damaged." ),
2379 else
2380 add_msg_player_or_npc( m_bad, _( "Your %s is damaged." ), _( "<npcname>'s %s is damaged." ),
2382
2383 }
2384}
static const efftype_id effect_under_op("under_operation")
static const efftype_id effect_infected("infected")
std::string body_part_name_accusative(body_part bp, int number)
Returns the matching accusative name of the body_part token, i.e.
Definition: bodypart.cpp:329
virtual int get_hp() const
Definition: creature.cpp:1658

References _, Creature::add_effect(), Creature::add_msg_player_or_npc(), apply_damage(), body_part_name_accusative(), effect_infected, effect_under_op, Creature::get_all_body_parts(), Creature::get_hp(), Creature::has_effect(), hp, m_bad, and rng().

Referenced by bionics_install_failure(), and bionics_uninstall_failure().

◆ do_skill_rust()

void Character::do_skill_rust ( )
protected

Definition at line 3564 of file character.cpp.

3565{
3566 const int rust_rate_tmp = rust_rate();
3567 static const std::string PRED2( "PRED2" );
3568 static const std::string PRED3( "PRED3" );
3569 static const std::string PRED4( "PRED4" );
3570 for( std::pair<const skill_id, SkillLevel> &pair : *_skills ) {
3571 const Skill &aSkill = *pair.first;
3572 SkillLevel &skill_level_obj = pair.second;
3573
3574 if( aSkill.is_combat_skill() &&
3575 ( ( has_trait_flag( PRED2 ) && calendar::once_every( 8_hours ) ) ||
3576 ( has_trait_flag( PRED3 ) && calendar::once_every( 4_hours ) ) ||
3577 ( has_trait_flag( PRED4 ) && calendar::once_every( 3_hours ) ) ) ) {
3578 // Their brain is optimized to remember this
3579 if( one_in( 13 ) ) {
3580 // They've already passed the roll to avoid rust at
3581 // this point, but print a message about it now and
3582 // then.
3583 //
3584 // 13 combat skills.
3585 // This means PRED2/PRED3/PRED4 think of hunting on
3586 // average every 8/4/3 hours, enough for immersion
3587 // without becoming an annoyance.
3588 //
3589 add_msg_if_player( _( "Your heart races as you recall your most recent hunt." ) );
3590 mod_stim( 1 );
3591 }
3592 continue;
3593 }
3594
3595 const bool charged_bio_mem = get_power_level() > bio_memory->power_trigger &&
3597 const int oldSkillLevel = skill_level_obj.level();
3598 if( skill_level_obj.rust( charged_bio_mem, rust_rate_tmp ) ) {
3600 _( "Your knowledge of %s begins to fade, but your memory banks retain it!" ), aSkill.name() );
3602 }
3603 const int newSkill = skill_level_obj.level();
3604 if( newSkill < oldSkillLevel ) {
3605 add_msg_if_player( m_bad, _( "Your skill in %s has reduced to %d!" ), aSkill.name(), newSkill );
3606 }
3607 }
3608}
bool has_trait_flag(const std::string &b) const
Returns true if player has a trait with a flag.
Definition: mutation.cpp:108
int rust_rate() const
Returns the player's skill rust rate.
Definition: character.cpp:3361
void mod_stim(int mod)
Definition: character.cpp:7025
int level() const
Definition: skill.h:125
bool rust(bool charged_bio_mem, int character_rate)
Definition: skill.cpp:269
Definition: skill.h:33
std::string name() const
Definition: skill.h:68
bool is_combat_skill() const
Definition: skill.cpp:211
units::energy power_trigger
Power cost when the bionic's special effect is triggered.
Definition: bionics.h:43

References _, _skills, Creature::add_msg_if_player(), bio_memory, get_power_level(), has_active_bionic(), has_trait_flag(), Skill::is_combat_skill(), SkillLevel::level(), m_bad, m_warning, mod_power_level(), mod_stim(), Skill::name(), calendar::once_every(), one_in(), bionic_data::power_trigger, SkillLevel::rust(), and rust_rate().

Referenced by update_body().

◆ dodge_roll()

float Character::dodge_roll ( )
overridevirtual

Implements Creature.

Definition at line 852 of file melee.cpp.

853{
854 return get_dodge() * 5;
855}
float get_dodge() const override
Definition: melee.cpp:809

References get_dodge().

◆ drench()

void Character::drench ( int  saturation,
const body_part_set flags,
bool  ignore_waterproof 
)

Drenches the player with water, saturation is the percent gotten wet.

Definition at line 1759 of file suffer.cpp.

1760{
1761 if( saturation < 1 ) {
1762 return;
1763 }
1764
1765 // OK, water gets in your AEP suit or whatever. It wasn't built to keep you dry.
1767 ( !ignore_waterproof && is_waterproof( flags ) ) ) {
1768 return;
1769 }
1770
1771 // Make the body wet
1772 for( const body_part bp : all_body_parts ) {
1773 // Different body parts have different size, they can only store so much water
1774 int bp_wetness_max = 0;
1775 if( flags.test( bp ) ) {
1776 bp_wetness_max = drench_capacity[bp];
1777 }
1778
1779 if( bp_wetness_max == 0 ) {
1780 continue;
1781 }
1782 // Different sources will only make the bodypart wet to a limit
1783 int source_wet_max = saturation * bp_wetness_max * 2 / 100;
1784 int wetness_increment = ignore_waterproof ? 100 : 2;
1785 // Respect maximums
1786 const int wetness_max = std::min( source_wet_max, bp_wetness_max );
1787 if( body_wetness[bp] < wetness_max ) {
1788 body_wetness[bp] = std::min( wetness_max, body_wetness[bp] + wetness_increment );
1789 }
1790 }
1791
1794 get_value( "waterproof_scent" ).empty() ) {
1795 add_msg_if_player( m_info, _( "The water wash away the scent." ) );
1796 restore_scent();
1797 }
1798
1799 if( is_weak_to_water() ) {
1800 add_msg_if_player( m_bad, _( "You feel the water burning your skin." ) );
1801 }
1802
1803 // Remove onfire effect
1804 if( saturation > 10 || x_in_y( saturation, 10 ) ) {
1806 }
1807}
bool is_waterproof(const body_part_set &parts) const
Definition: character.cpp:8951
bool is_weak_to_water() const
Definition: mutation.cpp:414
void restore_scent()
restore scent after masked_scent effect run out or is removed by water
Definition: character.cpp:8720
static const trait_id trait_DEBUG_NOTEMP("DEBUG_NOTEMP")
static const efftype_id effect_masked_scent("masked_scent")
static const trait_id trait_SHELL2("SHELL2")
static const efftype_id effect_onfire("onfire")

References _, Creature::add_msg_if_player(), all_body_parts, body_wetness, bp_torso, drench_capacity, effect_masked_scent, effect_onfire, Creature::get_value(), has_active_mutation(), Creature::has_effect(), has_trait(), is_waterproof(), is_weak_to_water(), m_bad, m_info, Creature::remove_effect(), restore_scent(), body_part_set::test(), trait_DEBUG_NOTEMP, trait_SHELL2, and x_in_y().

Referenced by character_funcs::do_pause(), game::place_player(), and avatar_action::swim().

◆ drench_mut_calc()

void Character::drench_mut_calc ( )

Recalculates mutation drench protection for all bodyparts (ignored/good/neutral stats)

Definition at line 7773 of file character.cpp.

7774{
7775 for( const body_part bp : all_body_parts ) {
7776 int ignored = 0;
7777 int neutral = 0;
7778 int good = 0;
7779
7780 for( const trait_id &iter : get_mutations() ) {
7781 const mutation_branch &mdata = iter.obj();
7782 const auto wp_iter = mdata.protection.find( bp );
7783 if( wp_iter != mdata.protection.end() ) {
7784 ignored += wp_iter->second.x;
7785 neutral += wp_iter->second.y;
7786 good += wp_iter->second.z;
7787 }
7788 }
7789
7790 mut_drench[bp][WT_GOOD] = good;
7792 mut_drench[bp][WT_IGNORED] = ignored;
7793 }
7794}
@ good
Item should display as green (action possible at the moment)
std::map< body_part, tripoint > protection
Definition: mutation.h:267

References all_body_parts, get_mutations(), mut_drench, neutral, mutation_branch::protection, WT_GOOD, WT_IGNORED, and WT_NEUTRAL.

Referenced by avatar::load(), mutate_towards(), remove_mutation(), and game::start_game().

◆ drop() [1/2]

void Character::drop ( const drop_locations what,
const tripoint target,
bool  stash = false 
)
virtual

Reimplemented in npc.

Definition at line 2445 of file character.cpp.

2447{
2448 if( what.empty() ) {
2449 return;
2450 }
2451
2452 if( rl_dist( pos(), target ) > 1 || !( stash || get_map().can_put_items( target ) ) ) {
2453 add_msg_player_or_npc( m_info, _( "You can't place items here!" ),
2454 _( "<npcname> can't place items here!" ) );
2455 return;
2456 }
2457
2458 if( stash ) {
2459 assign_activity( stash_activity_actor( *this, what, target - pos() ) );
2460 } else {
2461 assign_activity( drop_activity_actor( *this, what, false, target - pos() ) );
2462 }
2463}

References _, Creature::add_msg_player_or_npc(), assign_activity(), get_map(), m_info, pos(), and rl_dist().

◆ drop() [2/2]

void Character::drop ( item_location  loc,
const tripoint where 
)

Drops an item to the specified location.

Definition at line 2423 of file character.cpp.

2424{
2425 item &oThisItem = *loc;
2426 if( is_wielding( oThisItem ) ) {
2427 const auto ret = can_unwield( *loc );
2428
2429 if( !ret.success() ) {
2430 add_msg( m_info, "%s", ret.c_str() );
2431 return;
2432 }
2433 } else if( is_wearing( oThisItem ) ) {
2434 const auto ret = as_player()->can_takeoff( *loc );
2435
2436 if( !ret.success() ) {
2437 add_msg( m_info, "%s", ret.c_str() );
2438 return;
2439 }
2440 }
2441
2442 drop( { drop_location( loc, loc->count() ) }, where );
2443}
ret_val< bool > can_takeoff(const item &it, const std::list< item > *res=nullptr) const
Check if character is capable of taking off given item.
Definition: character.cpp:2988
void drop(item_location loc, const tripoint &where)
Drops an item to the specified location.
Definition: character.cpp:2423
iuse_location drop_location

References add_msg(), Creature::as_player(), can_takeoff(), can_unwield(), item::count(), drop(), is_wearing(), is_wielding(), m_info, and cata::hash64_detail::ret.

Referenced by game::drop(), npc::drop(), drop(), game::drop_in_direction(), monexamine::give_items_to(), harvest_common(), i_add_or_drop(), examine_item_menu::run(), suffer_from_schizophrenia(), and takeoff().

◆ drop_invalid_inventory()

void Character::drop_invalid_inventory ( )

Definition at line 3159 of file character.cpp.

3160{
3161 bool dropped_liquid = false;
3162 for( const std::list<item> *stack : inv.const_slice() ) {
3163 const item &it = stack->front();
3164 if( it.made_of( LIQUID ) ) {
3165 dropped_liquid = true;
3166 get_map().add_item_or_charges( pos(), it );
3167 // must be last
3168 i_rem( &it );
3169 }
3170 }
3171 if( dropped_liquid ) {
3172 add_msg_if_player( m_bad, _( "Liquid from your inventory has leaked onto the ground." ) );
3173 }
3174
3175 if( volume_carried() > volume_capacity() ) {
3176 auto items_to_drop = inv.remove_randomly_by_volume( volume_carried() - volume_capacity() );
3178 }
3179}
std::list< item > remove_randomly_by_volume(const units::volume &volume)
Randomly select items until the volume quota is filled.
Definition: inventory.cpp:758
const_invslice const_slice() const
Definition: inventory.cpp:143

References _, map::add_item_or_charges(), Creature::add_msg_if_player(), inventory::const_slice(), get_map(), i_rem(), inv, LIQUID, m_bad, item::made_of(), pos(), put_into_vehicle_or_drop(), inventory::remove_randomly_by_volume(), tumbling, volume_capacity(), and volume_carried().

Referenced by absorb_hit(), player_activity::do_turn(), npc::execute_action(), process_turn(), and npc_trading::trade().

◆ eat()

bool Character::eat ( item food,
bool  force = false 
)

Used for eating entered comestible, returns true if comestible is successfully eaten.

Definition at line 828 of file consumption.cpp.

829{
830 if( !food.is_food() ) {
831 return false;
832 }
833
834 const auto ret = force ? can_eat( food ) : will_eat( food, is_player() );
835 if( !ret.success() ) {
836 return false;
837 }
838
839 if( has_effect( effect_bloated ) &&
840 ( compute_effective_nutrients( food ).kcal > 0 || food.get_comestible()->quench > 0 ) &&
841 !food.has_flag( flag_NO_BLOAT ) ) {
842 add_msg_if_player( _( "You force yourself to vomit to make space for %s." ), food.tname() );
843 vomit();
844 }
845
846 int charges_used = 0;
847 if( food.type->has_use() ) {
848 if( !food.type->can_use( "DOGFOOD" ) &&
849 !food.type->can_use( "CATFOOD" ) &&
850 !food.type->can_use( "BIRDFOOD" ) &&
851 !food.type->can_use( "CATTLEFODDER" ) ) {
852 charges_used = food.type->invoke( *this->as_player(), food, pos() );
853 if( charges_used <= 0 ) {
854 return false;
855 }
856 }
857 }
858
859 // Note: the block below assumes we decided to eat it
860 // No coming back from here
861
862 const int nutr = nutrition_for( food );
863 const bool spoiled = food.rotten();
864
865 // The item is solid food
866 const bool chew = food.get_comestible()->comesttype == comesttype_FOOD ||
868 // This item is a drink and not a solid food (and not a thick soup)
869 const bool drinkable = !chew && food.get_comestible()->comesttype == comesttype_DRINK;
870 // If neither of the above is true then it's a drug and shouldn't get mealtime penalty/bonus
871
872 const bool saprophage = has_trait( trait_SAPROPHAGE );
873 if( spoiled && !saprophage ) {
874 add_msg_if_player( m_bad, _( "Ick, this %s doesn't taste so good…" ), food.tname() );
877 add_effect( effect_foodpoison, rng( 6_minutes, ( nutr + 1 ) * 6_minutes ) );
878 }
879 } else if( spoiled && saprophage ) {
880 add_msg_if_player( m_good, _( "Mmm, this %s tastes delicious…" ), food.tname() );
881 }
882 if( !consume_effects( food ) ) {
883 // Already consumed by using `food.type->invoke`?
884 if( charges_used > 0 ) {
885 food.mod_charges( -charges_used );
886 }
887 return false;
888 }
889 food.mod_charges( -1 );
890
891 const bool amorphous = has_trait( trait_AMORPHOUS );
892 int mealtime = 250;
893 if( drinkable || chew ) {
894 // Those bonuses/penalties only apply to food
895 // Not to smoking weed or applying bandages!
898 mealtime /= 2;
899 } else if( has_trait( trait_SHARKTEETH ) ) {
900 // SHARKBAIT! HOO HA HA!
901 mealtime /= 3;
902 } else if( has_trait( trait_GOURMAND ) ) {
903 // Don't stack those two - that would be 25 moves per item
904 mealtime -= 100;
905 }
906
907 if( has_trait( trait_BEAK_HUM ) && !drinkable ) {
908 // Much better than PROBOSCIS but still optimized for fluids
909 mealtime += 200;
910 } else if( has_trait( trait_SABER_TEETH ) ) {
911 // They get In The Way
912 mealtime += 250;
913 }
914
915 if( amorphous ) {
916 mealtime *= 1.1;
917 // Minor speed penalty for having to flow around it
918 // rather than just grab & munch
919 }
920 }
921
922 moves -= mealtime;
923
924 // If it's poisonous... poison us.
925 // TODO: Move this to a flag
926 if( food.poison > 0 && !has_trait( trait_POISRESIST ) &&
928 if( food.poison >= rng( 2, 4 ) ) {
929 add_effect( effect_poison, food.poison * 10_minutes );
930 }
931
932 add_effect( effect_foodpoison, food.poison * 30_minutes );
933 }
934
935 if( food.has_flag( flag_HIDDEN_HALLU ) ) {
936 if( !has_effect( effect_hallu ) ) {
937 add_effect( effect_hallu, 6_hours );
938 }
939 }
940
941 if( amorphous ) {
942 add_msg_player_or_npc( _( "You assimilate your %s." ), _( "<npcname> assimilates a %s." ),
943 food.tname() );
944 } else if( drinkable ) {
945 add_msg_player_or_npc( _( "You drink your %s." ), _( "<npcname> drinks a %s." ),
946 food.tname() );
947 } else if( chew ) {
948 add_msg_player_or_npc( _( "You eat your %s." ), _( "<npcname> eats a %s." ),
949 food.tname() );
950 }
951
952 if( food.get_comestible()->tool->tool ) {
953 // Tools like lighters get used
954 use_charges( food.get_comestible()->tool, 1 );
955 }
956
958 add_effect( effect_fungus, 1_turns, num_bp );
959 }
960
961 // Chance to become parasitised
963 if( food.get_comestible()->parasites > 0 && !food.has_flag( flag_NO_PARASITES ) &&
964 one_in( food.get_comestible()->parasites ) ) {
965 switch( rng( 0, 3 ) ) {
966 case 0:
967 add_effect( effect_tapeworm, 1_turns, num_bp );
968 break;
969 case 1:
970 if( !has_trait( trait_ACIDBLOOD ) ) {
972 }
973 break;
974 case 2:
976 break;
977 case 3:
979 }
980 }
981 }
982
983 for( const std::pair<const diseasetype_id, int> &elem : food.get_comestible()->contamination ) {
984 if( rng( 1, 100 ) <= elem.second ) {
985 expose_to_disease( elem.first );
986 }
987 }
988
989 consumption_history->elems.emplace_back( food );
990 // Clean out consumption_history so it doesn't get bigger than needed.
991 while( consumption_history->elems.front().time < calendar::turn - 2_days ) {
992 consumption_history->elems.pop_front();
993 }
994
995 return true;
996}
void expose_to_disease(diseasetype_id dis_type)
Determine if character is susceptible to dis_type and if so apply the symptoms.
Definition: character.cpp:1545
pimpl< consumption_history_t > consumption_history
Definition: character.h:1553
ret_val< edible_rating > will_eat(const item &food, bool interactive=false) const
Same as can_eat, but takes consequences into account.
bool rotten() const
returns true if item is now rotten after all shelf life has elapsed
Definition: item.h:848
void mod_charges(int mod)
Modify the charges of this item, only use for items counted by charges! The item must have enough cha...
Definition: item.cpp:9721
int poison
Definition: item.h:2201
static const efftype_id effect_bloodworms("bloodworms")
static const efftype_id effect_fungus("fungus")
static const std::string flag_FUNGAL_VECTOR("FUNGAL_VECTOR")
static const trait_id trait_SHARKTEETH("SHARKTEETH")
static const trait_id trait_EATDEAD("EATDEAD")
static const trait_id trait_SABER_TEETH("SABER_TEETH")
static const trait_id trait_M_IMMUNE("M_IMMUNE")
static const efftype_id effect_hallu("hallu")
static const trait_id trait_BEAK_HUM("BEAK_HUM")
static const trait_id trait_PARAIMMUNE("PARAIMMUNE")
static const trait_id trait_MANDIBLES("MANDIBLES")
static const std::string flag_HIDDEN_HALLU("HIDDEN_HALLU")
static const efftype_id effect_paincysts("paincysts")
static const std::string flag_NO_PARASITES("NO_PARASITES")
static const trait_id trait_AMORPHOUS("AMORPHOUS")
static const trait_id trait_MOUTH_TENTACLES("MOUTH_TENTACLES")
static const efftype_id effect_poison("poison")
static const efftype_id effect_foodpoison("foodpoison")
static const trait_id trait_FANGS_SPIDER("FANGS_SPIDER")
static const trait_id trait_POISRESIST("POISRESIST")
static const trait_id trait_ACIDBLOOD("ACIDBLOOD")
static const efftype_id effect_brainworms("brainworms")
int chew(player *, item *, bool, const tripoint &)
Definition: iuse.cpp:1098

References _, Creature::add_effect(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), Creature::as_player(), bio_digestion, can_eat(), itype::can_use(), iuse::chew(), comesttype_DRINK(), comesttype_FOOD(), compute_effective_nutrients(), consume_effects(), consumption_history, effect_bloated, effect_bloodworms, effect_brainworms, effect_foodpoison, effect_fungus, effect_hallu, effect_paincysts, effect_poison, effect_tapeworm, expose_to_disease(), flag_FUNGAL_VECTOR(), flag_HIDDEN_HALLU(), flag_NO_BLOAT(), flag_NO_PARASITES(), flag_USE_EAT_VERB(), item::get_comestible(), has_bionic(), Creature::has_effect(), item::has_flag(), has_trait(), itype::has_use(), itype::invoke(), item::is_food(), Creature::is_player(), m_bad, m_good, item::mod_charges(), Creature::moves, num_bp, nutrition_for(), one_in(), item::poison, pos(), cata::hash64_detail::ret, rng(), item::rotten(), item::tname(), trait_ACIDBLOOD, trait_AMORPHOUS, trait_BEAK_HUM, trait_EATDEAD, trait_FANGS_SPIDER, trait_GOURMAND, trait_M_IMMUNE, trait_MANDIBLES, trait_MOUTH_TENTACLES, trait_PARAIMMUNE, trait_POISRESIST, trait_SABER_TEETH, trait_SAPROPHAGE, trait_SAPROVORE, trait_SHARKTEETH, calendar::turn, item::type, use_charges(), vomit(), and will_eat().

Referenced by consume_item(), drink_nectar(), avatar_action::eat_here(), iexamine::flower_poppy(), vehicle::interact_with(), iexamine::keg(), and try_consume().

◆ encumb()

◆ enforce_minimum_healing()

void Character::enforce_minimum_healing ( )

Definition at line 4599 of file character.cpp.

4600{
4601 for( const bodypart_id &bp : get_all_body_parts() ) {
4602 if( get_part_healed_total( bp ) <= 0 ) {
4603 heal( bp, 1 );
4604 }
4605 set_part_healed_total( bp, 0 );
4606 }
4607}
void heal(const bodypart_id &healed, int dam)
Heals a body_part for dam.
Definition: character.cpp:8600
void set_part_healed_total(const bodypart_id &id, int set)
Definition: creature.cpp:1591
int get_part_healed_total(const bodypart_id &id) const
Definition: creature.cpp:1576

References Creature::get_all_body_parts(), Creature::get_part_healed_total(), heal(), and Creature::set_part_healed_total().

Referenced by update_body().

◆ enough_power_for()

bool Character::enough_power_for ( const bionic_id bid) const

Definition at line 1937 of file character.cpp.

1938{
1939 return power_level >= bid->power_activate;
1940}
units::energy power_level
Definition: character.h:2215

References bionic_data::power_activate, and power_level.

Referenced by activate_bionic(), and iexamine::fireplace().

◆ enumerate_unmet_requirements()

std::string Character::enumerate_unmet_requirements ( const item it,
const item context = item() 
) const

Returns a string of missed requirements (both stats and skills)

Definition at line 3337 of file character.cpp.

3338{
3339 std::vector<std::string> unmet_reqs;
3340
3341 const auto check_req = [ &unmet_reqs ]( const std::string & name, int cur, int req ) {
3342 if( cur < req ) {
3343 unmet_reqs.push_back( string_format( "%s %d", name, req ) );
3344 }
3345 };
3346
3347 check_req( _( "strength" ), get_str(), it.get_min_str() );
3348 check_req( _( "dexterity" ), get_dex(), it.type->min_dex );
3349 check_req( _( "intelligence" ), get_int(), it.type->min_int );
3350 check_req( _( "perception" ), get_per(), it.type->min_per );
3351
3352 for( const auto &elem : it.type->min_skills ) {
3353 check_req( context.contextualize_skill( elem.first )->name(),
3354 get_skill_level( elem.first, context ),
3355 elem.second );
3356 }
3357
3358 return enumerate_as_string( unmet_reqs );
3359}
int get_min_str() const
Definition: item.cpp:10044
skill_id contextualize_skill(const skill_id &id) const
Puts the skill in context of the item.
Definition: item.cpp:9966
int min_dex
Definition: itype.h:940
int min_int
Definition: itype.h:941
int min_per
Definition: itype.h:942
std::map< skill_id, int > min_skills
Definition: itype.h:938

References _, item::contextualize_skill(), enumerate_as_string(), get_dex(), get_int(), item::get_min_str(), get_per(), get_skill_level(), get_str(), itype::min_dex, itype::min_int, itype::min_per, itype::min_skills, name, Skill::name(), string_format(), and item::type.

Referenced by can_use(), and gunmod_inventory_preset::get_denial().

◆ env_surgery_bonus()

float Character::env_surgery_bonus ( int  radius)

Calculate skill bonus from tiles in radius.

Definition at line 2226 of file bionics.cpp.

2227{
2228 float bonus = 1.0;
2229 map &here = get_map();
2230 for( const tripoint &cell : here.points_in_radius( pos(), radius ) ) {
2231 if( here.furn( cell )->surgery_skill_multiplier ) {
2232 bonus = std::max( bonus, *here.furn( cell )->surgery_skill_multiplier );
2233 }
2234 }
2235 return bonus;
2236}
furn_id furn(const tripoint &p) const
Definition: map.cpp:1348
cata::optional< float > surgery_skill_multiplier
Definition: mapdata.h:521

References map::furn(), get_map(), map::points_in_radius(), pos(), and furn_t::surgery_skill_multiplier.

Referenced by bionics_adjusted_skill().

◆ environmental_revert_effect()

void Character::environmental_revert_effect ( )

Definition at line 785 of file character_turn.cpp.

786{
787 addictions.clear();
788 morale->clear();
789
792 set_thirst( 0 );
793 set_fatigue( 0 );
794 set_healthy( 0 );
795 set_healthy_mod( 0 );
796 set_stim( 0 );
797 set_pain( 0 );
798 set_painkiller( 0 );
799 set_rad( 0 );
801
804}
virtual void set_sleep_deprivation(int nsleep_deprivation)
Definition: character.cpp:4437
virtual void set_healthy_mod(int nhealthy_mod)
Definition: character.cpp:4242
virtual void set_stored_kcal(int kcal)
Setters for need values exclusive to characters.
Definition: character.cpp:4298
void set_pain(int npain) override
Sets new intensity of pain an reacts to it.
Definition: character.cpp:777
virtual void set_healthy(int nhealthy)
Setters for health values exclusive to characters.
Definition: character.cpp:4230
virtual void set_thirst(int nthirst)
Definition: character.cpp:4410
void set_all_parts_hp_to_max()
Definition: creature.cpp:1618

References addictions, max_stored_kcal(), morale, recalc_sight_limits(), reset_encumbrance(), Creature::set_all_parts_hp_to_max(), set_fatigue(), set_healthy(), set_healthy_mod(), set_pain(), set_painkiller(), set_rad(), set_sleep_deprivation(), set_stim(), set_stored_kcal(), and set_thirst().

◆ exclusive_flag_coverage()

body_part_set Character::exclusive_flag_coverage ( const std::string &  flag) const

Bitset of all the body parts covered only with items with flag (or nothing)

Definition at line 4032 of file character.cpp.

4033{
4035
4036 for( const auto &elem : worn ) {
4037 if( !elem.has_flag( flag ) ) {
4038 // Unset the parts covered by this item
4039 ret &= ~elem.get_covered_body_parts();
4040 }
4041 }
4042
4043 return ret;
4044}
static body_part_set all()
Definition: bodypart.h:233

References body_part_set::all(), cata::hash64_detail::ret, and worn.

Referenced by apply_wetness_morale(), mut_cbm_encumb(), mutation_attacks(), reset_stats(), and swim_speed().

◆ expose_to_disease()

void Character::expose_to_disease ( diseasetype_id  dis_type)

Determine if character is susceptible to dis_type and if so apply the symptoms.

Definition at line 1545 of file character.cpp.

1546{
1547 const cata::optional<int> &healt_thresh = dis_type->health_threshold;
1548 if( healt_thresh && healt_thresh.value() < get_healthy() ) {
1549 return;
1550 }
1551 const std::set<body_part> &bps = dis_type->affected_bodyparts;
1552 if( !bps.empty() ) {
1553 for( const body_part &bp : bps ) {
1554 add_effect( dis_type->symptoms, rng( dis_type->min_duration, dis_type->max_duration ), bp,
1555 rng( dis_type->min_intensity, dis_type->max_intensity ) );
1556 }
1557 } else {
1558 add_effect( dis_type->symptoms, rng( dis_type->min_duration, dis_type->max_duration ), num_bp,
1559 rng( dis_type->min_intensity, dis_type->max_intensity ) );
1560 }
1561}
virtual int get_healthy() const
Getters for health values exclusive to characters.
Definition: character.cpp:4129
time_duration min_duration
Definition: disease.h:26
cata::optional< int > health_threshold
If not empty this sets the health threshold above which you're immune to the disease.
Definition: disease.h:33
int max_intensity
Definition: disease.h:29
efftype_id symptoms
effect applied by this disease
Definition: disease.h:35
std::set< body_part > affected_bodyparts
Affected body parts.
Definition: disease.h:31
int min_intensity
Definition: disease.h:28
time_duration max_duration
Definition: disease.h:27

References Creature::add_effect(), disease_type::affected_bodyparts, get_healthy(), disease_type::health_threshold, disease_type::max_duration, disease_type::max_intensity, disease_type::min_duration, disease_type::min_intensity, num_bp, rng(), disease_type::symptoms, and cata::optional< T >::value().

Referenced by eat().

◆ extended_description()

std::string Character::extended_description ( ) const
overridevirtual

Implements Creature.

Reimplemented in npc.

Definition at line 6463 of file character.cpp.

6464{
6465 std::string ss;
6466 if( is_player() ) {
6467 // <bad>This is me, <player_name>.</bad>
6468 ss += string_format( _( "This is you - %s." ), name );
6469 } else {
6470 ss += string_format( _( "This is %s, %s" ), name, male ? _( "male" ) : _( "female" ) );
6471 }
6472
6473 ss += "\n--\n";
6474
6475 const std::vector<bodypart_id> &bps = get_all_body_parts( true );
6476 // Find length of bp names, to align
6477 // accumulate looks weird here, any better function?
6478 int longest = std::accumulate( bps.begin(), bps.end(), 0,
6479 []( int m, bodypart_id bp ) {
6480 return std::max( m, utf8_width( body_part_name_as_heading( bp->token, 1 ) ) );
6481 } );
6482
6483 // This is a stripped-down version of the body_window function
6484 // This should be extracted into a separate function later on
6485 for( const bodypart_id &bp : bps ) {
6486 // Hide appendix from the player
6487 if( bp->id.str() == "num_bp" ) {
6488 continue;
6489 }
6490 const std::string &bp_heading = body_part_name_as_heading( bp->token, 1 );
6491
6492 const nc_color state_col = limb_color( bp, true, true, true );
6493 nc_color name_color = state_col;
6494 std::pair<std::string, nc_color> hp_bar = get_hp_bar( get_part_hp_cur( bp ), get_part_hp_max( bp ),
6495 false );
6496
6497 ss += colorize( left_justify( bp_heading, longest ), name_color );
6498 ss += colorize( hp_bar.first, hp_bar.second );
6499 // Trailing bars. UGLY!
6500 // TODO: Integrate into get_hp_bar somehow
6501 ss += colorize( std::string( 5 - utf8_width( hp_bar.first ), '.' ), c_white );
6502 ss += "\n";
6503 }
6504
6505 ss += "--\n";
6506 ss += _( "Wielding:" ) + std::string( " " );
6507 if( weapon.is_null() ) {
6508 ss += _( "Nothing" );
6509 } else {
6510 ss += weapon.tname();
6511 }
6512
6513 ss += "\n";
6514 ss += _( "Wearing:" ) + std::string( " " );
6515 ss += enumerate_as_string( worn.begin(), worn.end(), []( const item & it ) {
6516 return it.tname();
6517 } );
6518
6519 return replace_colors( ss );
6520}
std::string left_justify(const std::string &str, const int width, const bool ignore_tags)
bool male
Definition: character.h:1530
std::string replace_colors(std::string text)
Replace special color tags (e.g.

References _, body_part_name_as_heading(), c_white, colorize(), enumerate_as_string(), Creature::get_all_body_parts(), get_hp_bar(), Creature::get_part_hp_cur(), Creature::get_part_hp_max(), int_id< T >::id(), item::is_null(), Creature::is_player(), left_justify(), limb_color(), male, name, replace_colors(), string_format(), item::tname(), utf8_width(), weapon, and worn.

Referenced by npc::extended_description().

◆ extraEncumbrance()

int Character::extraEncumbrance ( layer_level  level,
int  bp 
) const

Get encumbrance penalty per layer & body part.

Definition at line 3678 of file character.cpp.

3679{
3680 return encumbrance_cache->elems[bp].layer_penalty_details[static_cast<int>( level )].total;
3681}

References encumbrance_cache.

◆ fall_asleep() [1/2]

void Character::fall_asleep ( )

Adds "sleep" to the player.

Definition at line 9228 of file character.cpp.

9229{
9230 // Communicate to the player that he is using items on the floor
9231 std::string item_name = is_snuggling();
9232 if( item_name == "many" ) {
9233 if( one_in( 15 ) ) {
9234 add_msg_if_player( _( "You nestle your pile of clothes for warmth." ) );
9235 } else {
9236 add_msg_if_player( _( "You use your pile of clothes for warmth." ) );
9237 }
9238 } else if( item_name != "nothing" ) {
9239 if( one_in( 15 ) ) {
9240 add_msg_if_player( _( "You snuggle your %s to keep warm." ), item_name );
9241 } else {
9242 add_msg_if_player( _( "You use your %s to keep warm." ), item_name );
9243 }
9244 }
9246 if( get_stored_kcal() > max_stored_kcal() - bmr() / 4 &&
9248 if( is_avatar() ) {
9249 g->memorial().add( pgettext( "memorial_male", "Entered hibernation." ),
9250 pgettext( "memorial_female", "Entered hibernation." ) );
9251 }
9252
9253 add_msg_if_player( _( "You enter hibernation." ) );
9254 fall_asleep( 7_days );
9255 } else {
9257 _( "You need to be nearly full of food and water to enter hibernation." ) );
9258 }
9259 }
9260
9261 fall_asleep( 10_hours ); // default max sleep time.
9262}
static const trait_id trait_HIBERNATE("HIBERNATE")
int bmr() const
Definition: character.cpp:6820
std::string is_snuggling() const
Checks to see if the player is using floor items to keep warm, and return the name of one such item i...
Definition: character.cpp:9281

References _, Creature::add_msg_if_player(), bmr(), fall_asleep(), g, get_stored_kcal(), get_thirst(), has_active_mutation(), Creature::is_avatar(), is_snuggling(), m_bad, max_stored_kcal(), one_in(), pgettext(), thirsty, and trait_HIBERNATE.

Referenced by check_needs_extremes(), fall_asleep(), iexamine::flower_poppy(), hardcoded_effects(), introduce_into_anesthesia(), marloss_common(), iuse::mycus(), process_one_effect(), suffer_from_stimulants(), suffer_while_awake(), try_reject_mutagen(), activity_handlers::try_sleep_do_turn(), and mutagen_iv_actor::use().

◆ fall_asleep() [2/2]

void Character::fall_asleep ( const time_duration duration)

Definition at line 9264 of file character.cpp.

9265{
9266 if( activity ) {
9267 if( activity.id() == ACT_TRY_SLEEP ) {
9269 } else {
9271 }
9272 }
9273 add_effect( effect_sleep, duration );
9274}
void cancel_activity()
Definition: character.cpp:9188
void set_to_null()
This replaces the former usage act.type = ACT_NULL

References ACT_TRY_SLEEP, activity, Creature::add_effect(), cancel_activity(), effect_sleep, player_activity::id(), and player_activity::set_to_null().

◆ fall_damage_mod()

float Character::fall_damage_mod ( ) const
overridevirtual

Returns multiplier on fall damage at low velocity (knockback/pit/1 z-level, not 5 z-levels)

Dexterity decreases damage from falling Dodge decreases damage from falling

Implements Creature.

Definition at line 10620 of file character.cpp.

10621{
10622 if( has_effect_with_flag( "EFFECT_FEATHER_FALL" ) ) {
10623 return 0.0f;
10624 }
10625 float ret = 1.0f;
10626
10627 // Ability to land properly is 2x as important as dexterity itself
10628 /** @EFFECT_DEX decreases damage from falling */
10629
10630 /** @EFFECT_DODGE decreases damage from falling */
10631 float dex_dodge = dex_cur / 2.0 + get_skill_level( skill_dodge );
10632 // Penalize for wearing heavy stuff
10633 const float average_leg_encumb = ( encumb( bp_leg_l ) + encumb( bp_leg_r ) ) / 2.0;
10634 dex_dodge -= ( average_leg_encumb + encumb( bp_torso ) ) / 10;
10635 // But prevent it from increasing damage
10636 dex_dodge = std::max( 0.0f, dex_dodge );
10637 // 100% damage at 0, 75% at 10, 50% at 20 and so on
10638 ret *= ( 100.0f - ( dex_dodge * 4.0f ) ) / 100.0f;
10639
10640 if( has_trait( trait_PARKOUR ) ) {
10641 ret *= 2.0f / 3.0f;
10642 }
10643
10644 // TODO: Bonus for Judo, mutations. Penalty for heavy weight (including mutations)
10645 return std::max( 0.0f, ret );
10646}
static const trait_id trait_PARKOUR("PARKOUR")
bool has_effect_with_flag(const std::string &flag, body_part bp=num_bp) const
Check if creature has any effect with the given flag.
Definition: creature.cpp:1207

References bp_leg_l, bp_leg_r, bp_torso, dex_cur, encumb(), get_skill_level(), Creature::has_effect_with_flag(), has_trait(), cata::hash64_detail::ret, skill_dodge, and trait_PARKOUR.

Referenced by impact(), and iexamine::ledge().

◆ feed_furnace_with()

bool Character::feed_furnace_with ( item it)

Definition at line 1326 of file consumption.cpp.

1327{
1328 if( !can_feed_furnace_with( it ) ) {
1329 return false;
1330 }
1331 if( it.is_favorite &&
1332 !g->u.query_yn( _( "Are you sure you want to eat your favorited %s?" ), it.tname() ) ) {
1333 return false;
1334 }
1335
1336 const int consumed_charges = std::min( it.charges, it.charges_per_volume( furnace_max_volume ) );
1338
1339 if( energy == 0 ) {
1341 _( "You digest your %s, but fail to acquire energy from it." ),
1342 _( "<npcname> digests their %s for energy, but fails to acquire energy from it." ),
1343 it.tname() );
1344 } else if( is_max_power() ) {
1346 _( "You digest your %s, but you're fully powered already, so the energy is wasted." ),
1347 _( "<npcname> digests a %s for energy, they're fully powered already, so the energy is wasted." ),
1348 it.tname() );
1349 } else {
1350 const int profitable_energy = std::min( energy,
1352 if( it.count_by_charges() ) {
1354 vgettext( "You digest %d %s and recharge %d point of energy.",
1355 "You digest %d %s and recharge %d points of energy.",
1356 profitable_energy
1357 ),
1358 vgettext( "<npcname> digests %d %s and recharges %d point of energy.",
1359 "<npcname> digests %d %s and recharges %d points of energy.",
1360 profitable_energy
1361 ), consumed_charges, it.tname(), profitable_energy
1362 );
1363 } else {
1365 vgettext( "You digest your %s and recharge %d point of energy.",
1366 "You digest your %s and recharge %d points of energy.",
1367 profitable_energy
1368 ),
1369 vgettext( "<npcname> digests a %s and recharges %d point of energy.",
1370 "<npcname> digests a %s and recharges %d points of energy.",
1371 profitable_energy
1372 ), it.tname(), profitable_energy
1373 );
1374 }
1375 mod_power_level( units::from_kilojoule( profitable_energy ) );
1376 }
1377
1378 it.charges -= consumed_charges;
1379 mod_moves( -250 );
1380
1381 return true;
1382}
int get_acquirable_energy(const item &it, rechargeable_cbm cbm) const
bool can_feed_furnace_with(const item &it) const
bool is_max_power() const
Definition: character.cpp:1922
bool is_favorite
Definition: item.h:2236
quantity< int, energy_in_joule_tag > energy
Definition: units_energy.h:16
const char * vgettext(const char *msgid, const char *msgid_plural, size_t n)

References _, Creature::add_msg_player_or_npc(), can_feed_furnace_with(), item::charges, item::charges_per_volume(), item::count_by_charges(), units::from_kilojoule(), furnace, furnace_max_volume, g, get_acquirable_energy(), get_max_power_level(), get_power_level(), item::is_favorite, is_max_power(), m_info, Creature::mod_moves(), mod_power_level(), item::tname(), units::to_kilojoule(), and vgettext().

Referenced by consume_item().

◆ feed_reactor_with()

bool Character::feed_reactor_with ( item it)

Recharge CBMs whenever possible.

Returns
true when recharging was successful.

Definition at line 1282 of file consumption.cpp.

1283{
1284 if( !can_feed_reactor_with( it ) ) {
1285 return false;
1286 }
1287
1288 const auto iter = plut_charges.find( it.typeId() );
1289 const int max_amount = iter != plut_charges.end() ? iter->second : 0;
1290 const int amount = std::min( get_acquirable_energy( it, rechargeable_cbm::reactor ), max_amount );
1291
1292 if( amount >= PLUTONIUM_CHARGES * 10 &&
1293 !query_yn( _( "That is a LOT of plutonium. Are you sure you want that much?" ) ) ) {
1294 return false;
1295 }
1296
1297 add_msg_player_or_npc( _( "You add your %s to your reactor's tank." ),
1298 _( "<npcname> pours %s into their reactor's tank." ),
1299 it.tname() );
1300
1301 // TODO: Encapsulate
1302 tank_plut += amount;
1303 it.charges -= 1;
1304 mod_moves( -250 );
1305 return true;
1306}
bool can_feed_reactor_with(const item &it) const
Determine character's capability of recharging their CBMs.
const std::map< itype_id, int > plut_charges
static constexpr int PLUTONIUM_CHARGES

References _, Creature::add_msg_player_or_npc(), can_feed_reactor_with(), item::charges, get_acquirable_energy(), Creature::mod_moves(), plut_charges, PLUTONIUM_CHARGES, query_yn(), reactor, tank_plut, item::tname(), and item::typeId().

Referenced by consume_item().

◆ find_remote_fuel()

itype_id Character::find_remote_fuel ( bool  look_only = false)

Find fuel used by remote powered bionic.

Definition at line 1355 of file bionics.cpp.

1356{
1357 itype_id remote_fuel;
1358 map &here = get_map();
1359
1360 const std::vector<item *> cables = items_with( []( const item & it ) {
1361 return it.active && it.has_flag( flag_CABLE_SPOOL );
1362 } );
1363
1364 for( const item *cable : cables ) {
1365
1366 const cata::optional<tripoint> target = cable->get_cable_target( this, pos() );
1367 if( !target ) {
1368 if( here.is_outside( pos() ) && !is_night( calendar::turn ) &&
1369 cable->get_var( "state" ) == "solar_pack_link" ) {
1370 if( !look_only ) {
1371 set_value( "sunlight", "1" );
1372 }
1373 remote_fuel = fuel_type_sun_light;
1374 }
1375
1376 if( cable->get_var( "state" ) == "UPS_link" ) {
1377 static const item_filter used_ups = [&]( const item & itm ) {
1378 return itm.get_var( "cable" ) == "plugged_in";
1379 };
1380 if( !look_only ) {
1381 if( has_charges( itype_UPS_off, 1, used_ups ) ) {
1383 units::to_kilojoule( max_power_level ), used_ups ) ) );
1384 } else if( has_charges( itype_adv_UPS_off, 1, used_ups ) ) {
1386 units::to_kilojoule( max_power_level ), used_ups ) ) );
1387 } else {
1388 set_value( "rem_battery", std::to_string( 0 ) );
1389 }
1390 }
1391 remote_fuel = fuel_type_battery;
1392 }
1393 continue;
1394 }
1395 const optional_vpart_position vp = here.veh_at( *target );
1396 if( !vp ) {
1397 continue;
1398 }
1399 if( !look_only ) {
1400 set_value( "rem_battery", std::to_string( vp->vehicle().fuel_left( fuel_type_battery,
1401 true ) ) );
1402 }
1403 remote_fuel = fuel_type_battery;
1404 }
1405
1406 return remote_fuel;
1407}
static const itype_id fuel_type_battery("battery")
bool is_night(const time_point &p)
Returns true if it's currently night time - after dusk and before dawn.
Definition: calendar.cpp:137
units::energy max_power_level
Definition: character.h:2216
bool is_outside(const tripoint &p) const
Definition: map.cpp:2574
int charges_of(const itype_id &what, int limit=INT_MAX, const std::function< bool(const item &)> &filter=return_true< item >, std::function< void(int)> visitor=nullptr) const
Count maximum available charges from this instance and any contained items.
Definition: visitable.cpp:943

References item::active, visitable< Character >::charges_of(), flag_CABLE_SPOOL(), fuel_type_battery, fuel_type_sun_light, get_map(), has_charges(), item::has_flag(), is_night(), map::is_outside(), visitable< Character >::items_with(), itype_adv_UPS_off, itype_UPS_off, max_power_level, pos(), Creature::set_value(), units::to_kilojoule(), to_string(), calendar::turn, and map::veh_at().

Referenced by burn_fuel(), iuse::cable_attach(), draw_bionics_titlebar(), and process_bionic().

◆ flag_encumbrance()

void Character::flag_encumbrance ( )

Flag encumbrance for updating.

Definition at line 1743 of file character.cpp.

1744{
1745 check_encumbrance = true;
1746}

References check_encumbrance.

Referenced by monexamine::attach_bag_to(), item::on_drop(), item::on_pickup(), and item::on_wield().

◆ floor_bedding_warmth()

int Character::floor_bedding_warmth ( const tripoint pos)
static

Warmth from terrain, furniture, vehicle furniture and traps.

Can be negative.

Definition at line 9421 of file character.cpp.

9422{
9423 map &here = get_map();
9424 const trap &trap_at_pos = here.tr_at( pos );
9425 const ter_id ter_at_pos = here.ter( pos );
9426 const furn_id furn_at_pos = here.furn( pos );
9427 int floor_bedding_warmth = 0;
9428
9429 const optional_vpart_position vp = here.veh_at( pos );
9430 const cata::optional<vpart_reference> boardable = vp.part_with_feature( "BOARDABLE", true );
9431 // Search the floor for bedding
9432 if( furn_at_pos != f_null ) {
9434 } else if( !trap_at_pos.is_null() ) {
9436 } else if( boardable ) {
9437 floor_bedding_warmth += boardable->info().floor_bedding_warmth;
9438 } else if( ter_at_pos == t_improvised_shelter ) {
9439 floor_bedding_warmth -= 500;
9440 } else {
9441 floor_bedding_warmth -= 2000;
9442 }
9443
9444 return floor_bedding_warmth;
9445}
static int floor_bedding_warmth(const tripoint &pos)
Warmth from terrain, furniture, vehicle furniture and traps.
Definition: character.cpp:9421
const T & obj() const
Definition: ammo_effect.cpp:26
const trap & tr_at(const tripoint &p) const
Definition: map.cpp:5140
ter_id ter(const tripoint &p) const
Definition: map.cpp:1498
cata::optional< vpart_reference > part_with_feature(const std::string &f, bool unbroken) const
Definition: vehicle.cpp:2482
ter_id t_improvised_shelter
Definition: mapdata.cpp:718
int floor_bedding_warmth
Definition: mapdata.h:508
Definition: trap.h:86
int floor_bedding_warmth
Definition: trap.h:120

References f_null, floor_bedding_warmth(), furn_t::floor_bedding_warmth, trap::floor_bedding_warmth, map::furn(), get_map(), trap::is_null(), int_id< T >::obj(), optional_vpart_position::part_with_feature(), pos(), t_improvised_shelter, map::ter(), map::tr_at(), and map::veh_at().

Referenced by floor_bedding_warmth(), and floor_warmth().

◆ floor_item_warmth()

int Character::floor_item_warmth ( const tripoint pos)
static

Warmth from clothing on the floor.

Definition at line 9447 of file character.cpp.

9448{
9449 int item_warmth = 0;
9450
9451 const auto warm = [&item_warmth]( const auto & stack ) {
9452 for( const item &elem : stack ) {
9453 if( !elem.is_armor() ) {
9454 continue;
9455 }
9456 // Items that are big enough and covers the torso are used to keep warm.
9457 // Smaller items don't do as good a job
9458 if( elem.volume() > 250_ml &&
9459 ( elem.covers( bp_torso ) || elem.covers( bp_leg_l ) ||
9460 elem.covers( bp_leg_r ) ) ) {
9461 item_warmth += 60 * elem.get_warmth() * elem.volume() / 2500_ml;
9462 }
9463 }
9464 };
9465
9466 map &here = get_map();
9467 if( !!here.veh_at( pos ) ) {
9469 false ) ) {
9470 vehicle *const veh = &vp->vehicle();
9471 const int cargo = vp->part_index();
9472 vehicle_stack vehicle_items = veh->get_items( cargo );
9473 warm( vehicle_items );
9474 }
9475 return item_warmth;
9476 }
9477 map_stack floor_items = here.i_at( pos );
9478 warm( floor_items );
9479 return item_warmth;
9480}
A vehicle as a whole with all its components.
Definition: vehicle.h:676
vehicle(const vproto_id &type_id, int init_veh_fuel=-1, int init_veh_status=-1)
Definition: vehicle.cpp:252
vehicle_stack get_items(int part) const
Definition: vehicle.cpp:5470
@ VPFLAG_CARGO
Definition: veh_type.h:62

References bp_leg_l, bp_leg_r, bp_torso, vehicle::get_items(), get_map(), map::i_at(), optional_vpart_position::part_with_feature(), pos(), map::veh_at(), vehicle::vehicle(), and VPFLAG_CARGO.

Referenced by floor_warmth().

◆ floor_warmth()

int Character::floor_warmth ( const tripoint pos) const

Final warmth from the floor.

Definition at line 9482 of file character.cpp.

9483{
9484 const int item_warmth = floor_item_warmth( pos );
9485 int bedding_warmth = floor_bedding_warmth( pos );
9486
9487 // If the PC has fur, etc, that will apply too
9488 int floor_mut_warmth = bodytemp_modifier_traits_floor();
9489 // DOWN does not provide floor insulation, though.
9490 // Better-than-light fur or being in one's shell does.
9491 if( ( !( has_trait( trait_DOWN ) ) ) && ( floor_mut_warmth >= 200 ) ) {
9492 bedding_warmth = std::max( 0, bedding_warmth );
9493 }
9494 return ( item_warmth + bedding_warmth + floor_mut_warmth );
9495}
static const trait_id trait_DOWN("DOWN")
static int floor_item_warmth(const tripoint &pos)
Warmth from clothing on the floor.
Definition: character.cpp:9447
int bodytemp_modifier_traits_floor() const
Correction factor of the body temperature due to traits and mutations for player lying on the floor.
Definition: character.cpp:9506

References bodytemp_modifier_traits_floor(), floor_bedding_warmth(), floor_item_warmth(), has_trait(), pos(), and trait_DOWN.

Referenced by update_bodytemp().

◆ footwear_factor()

double Character::footwear_factor ( ) const

Returns 1 if the player is wearing something on both feet, .5 if on one, and 0 if on neither.

Definition at line 8891 of file character.cpp.

8892{
8893 double ret = 0;
8894 if( wearing_something_on( bodypart_id( "foot_l" ) ) ) {
8895 ret += .5;
8896 }
8897 if( wearing_something_on( bodypart_id( "foot_r" ) ) ) {
8898 ret += .5;
8899 }
8900 return ret;
8901}

References cata::hash64_detail::ret, and wearing_something_on().

Referenced by is_immune_effect(), game::knockback(), rooted(), run_cost(), and game::walk_move().

◆ forced_dismount()

void Character::forced_dismount ( )

Definition at line 1069 of file character.cpp.

1070{
1072 bool mech = false;
1073 if( mounted_creature ) {
1074 auto mon = mounted_creature.get();
1075 if( mon->has_flag( MF_RIDEABLE_MECH ) && !mon->type->mech_weapon.is_empty() ) {
1076 mech = true;
1078 }
1079 mon->mounted_player_id = character_id();
1080 mon->remove_effect( effect_ridden );
1081 mon->add_effect( effect_ai_waiting, 5_turns );
1082 mounted_creature = nullptr;
1083 mon->mounted_player = nullptr;
1084 }
1085 std::vector<tripoint> valid;
1086 for( const tripoint &jk : get_map().points_in_radius( pos(), 1 ) ) {
1087 if( g->is_empty( jk ) ) {
1088 valid.push_back( jk );
1089 }
1090 }
1091 if( !valid.empty() ) {
1092 setpos( random_entry( valid ) );
1093 if( mech ) {
1094 add_msg_player_or_npc( m_bad, _( "You are ejected from your mech!" ),
1095 _( "<npcname> is ejected from their mech!" ) );
1096 } else {
1097 add_msg_player_or_npc( m_bad, _( "You fall off your mount!" ),
1098 _( "<npcname> falls off their mount!" ) );
1099 }
1100 const int dodge = get_dodge();
1101 const int damage = std::max( 0, rng( 1, 20 ) - rng( dodge, dodge * 2 ) );
1102 bodypart_id hit( "num_bp" );
1103 switch( rng( 1, 10 ) ) {
1104 case 1:
1105 if( one_in( 2 ) ) {
1106 hit = bodypart_id( "foot_l" );
1107 } else {
1108 hit = bodypart_id( "foot_r" );
1109 }
1110 break;
1111 case 2:
1112 case 3:
1113 case 4:
1114 if( one_in( 2 ) ) {
1115 hit = bodypart_id( "leg_l" );
1116 } else {
1117 hit = bodypart_id( "leg_r" );
1118 }
1119 break;
1120 case 5:
1121 case 6:
1122 case 7:
1123 if( one_in( 2 ) ) {
1124 hit = bodypart_id( "arm_l" );
1125 } else {
1126 hit = bodypart_id( "arm_r" );
1127 }
1128 break;
1129 case 8:
1130 case 9:
1131 hit = bodypart_id( "torso" );
1132 break;
1133 case 10:
1134 hit = bodypart_id( "head" );
1135 break;
1136 }
1137 if( damage > 0 ) {
1138 add_msg_if_player( m_bad, _( "You hurt yourself!" ) );
1139 deal_damage( nullptr, hit, damage_instance( DT_BASH, damage ) );
1140 if( is_avatar() ) {
1141 g->memorial().add(
1142 pgettext( "memorial_male", "Fell off a mount." ),
1143 pgettext( "memorial_female", "Fell off a mount." ) );
1144 }
1146 }
1147 add_effect( effect_downed, 5_turns, num_bp );
1148 } else {
1149 add_msg( m_debug, "Forced_dismount could not find a square to deposit player" );
1150 }
1151 if( is_avatar() ) {
1152 if( g->u.get_grab_type() != OBJECT_NONE ) {
1153 add_msg( m_warning, _( "You let go of the grabbed object." ) );
1154 g->u.grab( OBJECT_NONE );
1155 }
1157 if( g->u.is_auto_moving() || g->u.has_destination() || g->u.has_destination_activity() ) {
1158 g->u.clear_destination();
1159 }
1160 g->update_map( g->u );
1161 }
1162 if( activity ) {
1164 }
1165 moves -= 150;
1166}
static const efftype_id effect_downed("downed")
dealt_damage_instance deal_damage(Creature *source, bodypart_id bp, const damage_instance &d) override
Calls Creature::deal_damage and handles damaged effects (waking up, etc.)
Definition: character.cpp:8419
void check_dead_state()
This function checks the creatures is_dead_state and (if true) calls die.
Definition: creature.cpp:1845

References _, Creature::add_msg_player_or_npc(), character_id, effect_ai_waiting, effect_ridden, effect_riding, g, get_map(), m_bad, MF_RIDEABLE_MECH, mounted_creature, points_in_radius(), pos(), random_entry(), Creature::remove_effect(), visitable< Character >::remove_item(), setpos(), and weapon.

Referenced by Creature::add_effect(), check_mount_is_spooked(), monster::die(), and monster::setpos().

◆ fuel_bionic_with()

bool Character::fuel_bionic_with ( item it)

Definition at line 1384 of file consumption.cpp.

1385{
1386 if( !can_fuel_bionic_with( it ) ) {
1387 return false;
1388 }
1389
1391
1392 const int loadable = std::min( it.charges, get_fuel_capacity( it.typeId() ) );
1393 const std::string str_loaded = get_value( it.typeId().str() );
1394 int loaded = 0;
1395 if( !str_loaded.empty() ) {
1396 loaded = std::stoi( str_loaded );
1397 }
1398
1399 const std::string new_charge = std::to_string( loadable + loaded );
1400
1401 it.charges -= loadable;
1402 // Type and amount of fuel
1403 set_value( it.typeId().str(), new_charge );
1406 //~ %1$i: charge number, %2$s: item name, %3$s: bionics name
1407 vgettext( "You load %1$i charge of %2$s in your %3$s.",
1408 "You load %1$i charges of %2$s in your %3$s.", loadable ),
1409 //~ %1$i: charge number, %2$s: item name, %3$s: bionics name
1410 vgettext( "<npcname> load %1$i charge of %2$s in their %3$s.",
1411 "<npcname> load %1$i charges of %2$s in their %3$s.", loadable ), loadable, it.tname(), bio->name );
1412 mod_moves( -250 );
1413 return true;
1414}
bionic_id get_most_efficient_bionic(const std::vector< bionic_id > &bids) const
Return bionic_id of bionic of most fuel efficient bionic.
Definition: character.cpp:1872
bool can_fuel_bionic_with(const item &it) const
Returns true if the character can fuel a bionic with the item.
Definition: character.cpp:1830
int get_fuel_capacity(const itype_id &fuel) const
Return available space to store specified fuel.
Definition: character.cpp:2006

References Creature::add_msg_player_or_npc(), can_fuel_bionic_with(), item::charges, get_bionic_fueled_with(), get_fuel_capacity(), get_most_efficient_bionic(), Creature::get_value(), m_info, Creature::mod_moves(), bionic_data::name, Creature::set_value(), string_id< T >::str(), item::tname(), to_string(), item::typeId(), update_fuel_storage(), and vgettext().

Referenced by consume_item().

◆ fun_for()

std::pair< int, int > Character::fun_for ( const item comest) const

Handles the enjoyability value for a comestible.

First value is enjoyability, second is cap.

Definition at line 472 of file consumption.cpp.

473{
474 if( !comest.is_comestible() ) {
475 return std::pair<int, int>( 0, 0 );
476 }
477
478 // As float to avoid rounding too many times
479 float fun = comest.get_comestible_fun();
480 float fun_max;
481
482 // Lupines/Felines like dog/cat food. Won't skip the rotting check.
483 // This is specifically so that Lupines/Felines don't get the harsher
484 // morale penalties from rotting cat/dog food.
485 if( ( comest.has_flag( flag_LUPINE ) && has_trait( trait_THRESH_LUPINE ) ) ||
486 ( comest.has_flag( flag_FELINE ) && has_trait( trait_THRESH_FELINE ) ) ) {
487 if( fun < 0 ) {
488 fun = -fun / 2;
489 }
490 }
491
492 const float relative_rot = comest.get_relative_rot();
493
494 if( relative_rot > 1.0f && !has_trait( trait_SAPROPHAGE ) && !has_trait( trait_SAPROVORE ) ) {
495 // Rotten food should be pretty disgusting.
496 // Baseline minumum is the same as eating raw meat as a normal human being.
497 fun = std::min( fun - 5, -10.0f );
498 fun_max = fun * 6;
499 } else {
500 // Food is less enjoyable when eaten too often.
501 if( fun > 0 || comest.has_flag( flag_NEGATIVE_MONOTONY_OK ) ) {
502 for( const consumption_event &event : consumption_history->elems ) {
503 if( event.time > calendar::turn - 2_days && event.type_id == comest.typeId() &&
504 event.component_hash == comest.make_component_hash() ) {
505 fun -= comest.get_comestible()->monotony_penalty;
506 // This effect can't drop fun below 0, unless the food has the right flag.
507 // 0 is the lowest we'll go, no need to keep looping.
508 if( fun <= 0 && !comest.has_flag( flag_NEGATIVE_MONOTONY_OK ) ) {
509 fun = 0;
510 break;
511 }
512 }
513 }
514 }
515
516 fun_max = fun < 0 ? fun * 6 : fun * 3;
517
518 // I'd assume since gourmands are just big eaters they still can't stand rotten food.
519 if( has_trait( trait_GOURMAND ) ) {
520 if( fun < -1 ) {
521 fun_max = fun;
522 fun /= 2;
523 } else if( fun > 0 ) {
524 fun_max *= 3;
525 fun = fun * 3 / 2;
526 }
527 }
528 }
529
530 return { static_cast< int >( fun ), static_cast< int >( fun_max ) };
531}
uint64_t make_component_hash() const
Creates a hash from the itype_ids of this item's components.
Definition: item.cpp:8918
int get_comestible_fun() const
Definition: item.cpp:5487
static const std::string flag_NEGATIVE_MONOTONY_OK("NEGATIVE_MONOTONY_OK")
time_point time
Definition: consumption.h:15
uint64_t component_hash
Definition: consumption.h:17
itype_id type_id
Definition: consumption.h:16

References consumption_event::component_hash, consumption_history, flag_FELINE(), flag_LUPINE(), flag_NEGATIVE_MONOTONY_OK(), item::get_comestible(), item::get_comestible_fun(), item::get_relative_rot(), item::has_flag(), has_trait(), item::is_comestible(), item::make_component_hash(), consumption_event::time, trait_GOURMAND, trait_SAPROPHAGE, trait_SAPROVORE, trait_THRESH_FELINE, trait_THRESH_LUPINE, calendar::turn, consumption_event::type_id, and item::typeId().

Referenced by comestible_inventory_preset::comestible_inventory_preset(), find_auto_consume(), item::food_info(), and modify_morale().

◆ get_acquirable_energy() [1/2]

int Character::get_acquirable_energy ( const item it) const

Definition at line 1479 of file consumption.cpp.

1480{
1482}

References get_acquirable_energy(), and get_cbm_rechargeable_with().

◆ get_acquirable_energy() [2/2]

int Character::get_acquirable_energy ( const item it,
rechargeable_cbm  cbm 
) const

Definition at line 1433 of file consumption.cpp.

1434{
1435 switch( cbm ) {
1437 break;
1438
1440 if( it.charges > 0 ) {
1441 const auto iter = plut_charges.find( it.typeId() );
1442 return iter != plut_charges.end() ? it.charges * iter->second : 0;
1443 }
1444
1445 break;
1446
1448 units::volume consumed_vol = it.volume();
1449 units::mass consumed_mass = it.weight();
1451 const double n_stacks = static_cast<double>( it.charges_per_volume( furnace_max_volume ) ) /
1452 it.type->stack_size;
1453 consumed_vol = it.type->volume * n_stacks;
1454 // it.type->weight is in 10g units?
1455 consumed_mass = it.type->weight * 10 * n_stacks;
1456 }
1457 int amount = ( consumed_vol / 250_ml + consumed_mass / 1_gram ) / 9;
1458
1459 // TODO: JSONize.
1460 if( it.made_of( material_id( "leather" ) ) ) {
1461 amount /= 4;
1462 }
1463 if( it.made_of( material_id( "wood" ) ) ) {
1464 amount /= 2;
1465 }
1466
1467 return amount;
1468 }
1471 const int to_consume = std::min( it.charges, bid->fuel_capacity );
1472 const int to_charge = static_cast<int>( it.fuel_energy() * to_consume * bid->fuel_efficiency );
1473 return to_charge;
1474 }
1475
1476 return 0;
1477}
int fuel_capacity
How much fuel this bionic can hold.
Definition: bionics.h:67
units::mass weight
Weight of item ( or each stack member )
Definition: itype.h:967
int stack_size
Number of items per above volume for count_by_charges items.
Definition: itype.h:984
units::volume volume
Space occupied by items of this type CAUTION: value given is for a default-sized stack.
Definition: itype.h:976

References item::charges, item::charges_per_volume(), item::count_by_charges(), bionic_data::fuel_capacity, bionic_data::fuel_efficiency, item::fuel_energy(), furnace, furnace_max_volume, get_bionic_fueled_with(), get_most_efficient_bionic(), item::made_of(), none, other, plut_charges, reactor, itype::stack_size, item::type, item::typeId(), item::volume(), itype::volume, item::weight(), and itype::weight.

Referenced by feed_furnace_with(), feed_reactor_with(), and get_acquirable_energy().

◆ get_all_armor_type()

std::map< bodypart_id, int > Character::get_all_armor_type ( damage_type  dt,
const std::map< bodypart_id, std::vector< const item * > > &  clothing_map 
) const

Definition at line 6879 of file character.cpp.

6881{
6882 std::map<bodypart_id, int> ret;
6883 for( const bodypart_id &bp : get_all_body_parts() ) {
6884 ret.emplace( bp, 0 );
6885 }
6886
6887 for( std::pair<const bodypart_id, int> &per_bp : ret ) {
6888 const bodypart_id &bp = per_bp.first;
6889 switch( dt ) {
6890 case DT_TRUE:
6891 case DT_BIOLOGICAL:
6892 // Characters cannot resist this
6893 return ret;
6894 /* BASH, CUT, STAB, and BULLET don't benefit from the clothing_map optimization */
6895 // TODO: Fix that
6896 case DT_BASH:
6897 per_bp.second += get_armor_bash( bp );
6898 break;
6899 case DT_CUT:
6900 per_bp.second += get_armor_cut( bp );
6901 break;
6902 case DT_STAB:
6903 per_bp.second += get_armor_cut( bp ) * 0.8f;
6904 break;
6905 case DT_BULLET:
6906 per_bp.second += get_armor_bullet( bp );
6907 break;
6908 case DT_ACID:
6909 case DT_HEAT:
6910 case DT_COLD:
6911 case DT_ELECTRIC: {
6912 for( const item *it : clothing_map.at( bp ) ) {
6913 per_bp.second += it->damage_resist( dt );
6914 }
6915
6916 per_bp.second += mutation_armor( bp, dt );
6917 break;
6918 }
6919 case DT_NULL:
6920 case NUM_DT:
6921 debugmsg( "Invalid damage type: %d", dt );
6922 return ret;
6923 }
6924 }
6925
6926 return ret;
6927}
int get_armor_cut(bodypart_id bp) const override
Returns overall cutting resistance for the body_part.
Definition: character.cpp:6830
int get_armor_bullet(bodypart_id bp) const override
Returns overall bullet resistance for the body_part.
Definition: character.cpp:6835
int get_armor_bash(bodypart_id bp) const override
Returns overall bashing resistance for the body_part.
Definition: character.cpp:6825
resistances mutation_armor(bodypart_id bp) const
Returns resistances on a body part provided by mutations.
Definition: character.cpp:6390
@ DT_TRUE
Definition: damage.h:22
@ DT_NULL
Definition: damage.h:21
@ NUM_DT
Definition: damage.h:32
@ DT_BIOLOGICAL
Definition: damage.h:23

References debugmsg, DT_ACID, DT_BASH, DT_BIOLOGICAL, DT_BULLET, DT_COLD, DT_CUT, DT_ELECTRIC, DT_HEAT, DT_NULL, DT_STAB, DT_TRUE, Creature::get_all_body_parts(), get_armor_bash(), get_armor_bullet(), get_armor_cut(), mutation_armor(), NUM_DT, and cata::hash64_detail::ret.

Referenced by get_armor_fire().

◆ get_all_skills()

const SkillLevelMap & Character::get_all_skills ( ) const

Definition at line 3302 of file character.cpp.

3303{
3304 return *_skills;
3305}

References _skills.

Referenced by player::has_recipe_requirements(), lighting_crafting_speed_multiplier(), set_skills(), and memorial_logger::write().

◆ get_armor_acid()

int Character::get_armor_acid ( bodypart_id  bp) const

Returns overall acid resistance for the body part.

Definition at line 7010 of file character.cpp.

7011{
7012 return get_armor_type( DT_ACID, bp );
7013}
int get_armor_type(damage_type dt, bodypart_id bp) const override
Returns overall resistance to given type on the bod part.
Definition: character.cpp:6841

References DT_ACID, and get_armor_type().

◆ get_armor_bash()

int Character::get_armor_bash ( bodypart_id  bp) const
overridevirtual

Returns overall bashing resistance for the body_part.

Reimplemented from Creature.

Definition at line 6825 of file character.cpp.

6826{
6828}
int get_armor_bash_base(bodypart_id bp) const override
Returns bashing resistance from the creature and armor only.
Definition: character.cpp:6929
int armor_bash_bonus
Definition: creature.h:824

References Creature::armor_bash_bonus, and get_armor_bash_base().

Referenced by get_all_armor_type(), get_armor_type(), game::get_dangerous_tile(), and game::place_player().

◆ get_armor_bash_base()

int Character::get_armor_bash_base ( bodypart_id  bp) const
overridevirtual

Returns bashing resistance from the creature and armor only.

Reimplemented from Creature.

Definition at line 6929 of file character.cpp.

6930{
6931 int ret = 0;
6932 for( auto &i : worn ) {
6933 if( i.covers( bp->token ) ) {
6934 ret += i.bash_resist();
6935 }
6936 }
6937 for( const bionic_id &bid : get_bionics() ) {
6938 const auto bash_prot = bid->bash_protec.find( bp.id() );
6939 if( bash_prot != bid->bash_protec.end() ) {
6940 ret += bash_prot->second;
6941 }
6942 }
6943
6944 ret += mutation_armor( bp, DT_BASH );
6945 return ret;
6946}

References DT_BASH, get_bionics(), int_id< T >::id(), mutation_armor(), cata::hash64_detail::ret, and worn.

Referenced by get_armor_bash().

◆ get_armor_bullet()

int Character::get_armor_bullet ( bodypart_id  bp) const
overridevirtual

Returns overall bullet resistance for the body_part.

Reimplemented from Creature.

Definition at line 6835 of file character.cpp.

6836{
6838}
int get_armor_bullet_base(bodypart_id bp) const override
Returns cutting resistance from the creature and armor only.
Definition: character.cpp:6967
int armor_bullet_bonus
Definition: creature.h:826

References Creature::armor_bullet_bonus, and get_armor_bullet_base().

Referenced by get_all_armor_type(), and get_armor_type().

◆ get_armor_bullet_base()

int Character::get_armor_bullet_base ( bodypart_id  bp) const
overridevirtual

Returns cutting resistance from the creature and armor only.

Reimplemented from Creature.

Definition at line 6967 of file character.cpp.

6968{
6969 int ret = 0;
6970 for( auto &i : worn ) {
6971 if( i.covers( bp->token ) ) {
6972 ret += i.bullet_resist();
6973 }
6974 }
6975
6976 for( const bionic_id &bid : get_bionics() ) {
6977 const auto bullet_prot = bid->bullet_protec.find( bp.id() );
6978 if( bullet_prot != bid->bullet_protec.end() ) {
6979 ret += bullet_prot->second;
6980 }
6981 }
6982
6983 ret += mutation_armor( bp, DT_BULLET );
6984 return ret;
6985}

References DT_BULLET, get_bionics(), int_id< T >::id(), mutation_armor(), cata::hash64_detail::ret, and worn.

Referenced by get_armor_bullet().

◆ get_armor_cut()

int Character::get_armor_cut ( bodypart_id  bp) const
overridevirtual

Returns overall cutting resistance for the body_part.

Reimplemented from Creature.

Definition at line 6830 of file character.cpp.

6831{
6832 return get_armor_cut_base( bp ) + armor_cut_bonus;
6833}
int get_armor_cut_base(bodypart_id bp) const override
Returns cutting resistance from the creature and armor only.
Definition: character.cpp:6948
int armor_cut_bonus
Definition: creature.h:825

References Creature::armor_cut_bonus, and get_armor_cut_base().

Referenced by get_all_armor_type(), get_armor_type(), and map::player_in_field().

◆ get_armor_cut_base()

int Character::get_armor_cut_base ( bodypart_id  bp) const
overridevirtual

Returns cutting resistance from the creature and armor only.

Reimplemented from Creature.

Definition at line 6948 of file character.cpp.

6949{
6950 int ret = 0;
6951 for( auto &i : worn ) {
6952 if( i.covers( bp->token ) ) {
6953 ret += i.cut_resist();
6954 }
6955 }
6956 for( const bionic_id &bid : get_bionics() ) {
6957 const auto cut_prot = bid->cut_protec.find( bp.id() );
6958 if( cut_prot != bid->cut_protec.end() ) {
6959 ret += cut_prot->second;
6960 }
6961 }
6962
6963 ret += mutation_armor( bp, DT_CUT );
6964 return ret;
6965}

References DT_CUT, get_bionics(), int_id< T >::id(), mutation_armor(), cata::hash64_detail::ret, and worn.

Referenced by get_armor_cut().

◆ get_armor_fire()

std::map< bodypart_id, int > Character::get_armor_fire ( const std::map< bodypart_id, std::vector< const item * > > &  clothing_map) const

Returns overall fire resistance.

Definition at line 8207 of file character.cpp.

8209{
8210 return get_all_armor_type( DT_HEAT, clothing_map );
8211}
std::map< bodypart_id, int > get_all_armor_type(damage_type dt, const std::map< bodypart_id, std::vector< const item * > > &clothing_map) const
Definition: character.cpp:6879

References DT_HEAT, and get_all_armor_type().

Referenced by update_bodytemp().

◆ get_armor_type()

int Character::get_armor_type ( damage_type  dt,
bodypart_id  bp 
) const
overridevirtual

Returns overall resistance to given type on the bod part.

Implements Creature.

Definition at line 6841 of file character.cpp.

6842{
6843 switch( dt ) {
6844 case DT_TRUE:
6845 case DT_BIOLOGICAL:
6846 return 0;
6847 case DT_BASH:
6848 return get_armor_bash( bp );
6849 case DT_CUT:
6850 return get_armor_cut( bp );
6851 case DT_STAB:
6852 return get_armor_cut( bp ) * 0.8f;
6853 case DT_BULLET:
6854 return get_armor_bullet( bp );
6855 case DT_ACID:
6856 case DT_HEAT:
6857 case DT_COLD:
6858 case DT_ELECTRIC: {
6859 int ret = 0;
6860 for( auto &i : worn ) {
6861 if( i.covers( bp->token ) ) {
6862 ret += i.damage_resist( dt );
6863 }
6864 }
6865
6866 ret += mutation_armor( bp, dt );
6867 return ret;
6868 }
6869 case DT_NULL:
6870 case NUM_DT:
6871 // Let it error below
6872 break;
6873 }
6874
6875 debugmsg( "Invalid damage type: %d", dt );
6876 return 0;
6877}

References debugmsg, DT_ACID, DT_BASH, DT_BIOLOGICAL, DT_BULLET, DT_COLD, DT_CUT, DT_ELECTRIC, DT_HEAT, DT_NULL, DT_STAB, DT_TRUE, get_armor_bash(), get_armor_bullet(), get_armor_cut(), mutation_armor(), NUM_DT, cata::hash64_detail::ret, and worn.

Referenced by map::burn_body_part(), get_armor_acid(), and is_immune_field().

◆ get_auto_move_route()

std::vector< tripoint > & Character::get_auto_move_route ( )

Definition at line 10488 of file character.cpp.

10489{
10490 return auto_move_route;
10491}

References auto_move_route.

Referenced by game::cancel_activity_or_ignore_query(), game::cancel_activity_query(), npc::move(), and npc::move_to().

◆ get_base_traits()

std::vector< trait_id > Character::get_base_traits ( ) const

Get the idents of all base traits.

Definition at line 2852 of file newcharacter.cpp.

2853{
2854 return std::vector<trait_id>( my_traits.begin(), my_traits.end() );
2855}

References my_traits.

Referenced by avatar::create(), and set_description().

◆ get_bionic_fueled_with()

std::vector< bionic_id > Character::get_bionic_fueled_with ( const item it) const

Return bionic_id of bionics able to use it as fuel.

Definition at line 1846 of file character.cpp.

1847{
1848 std::vector<bionic_id> bionics;
1849
1850 for( const bionic_id &bid : get_bionics() ) {
1851 for( const itype_id &fuel : bid->fuel_opts ) {
1852 if( fuel == it.typeId() ) {
1853 bionics.emplace_back( bid );
1854 }
1855 }
1856 }
1857
1858 return bionics;
1859}

References get_bionics(), and item::typeId().

Referenced by burn_move_stamina(), fuel_bionic_with(), get_acquirable_energy(), game::on_move_effects(), reset_remote_fuel(), and update_fuel_storage().

◆ get_bionic_state()

bionic & Character::get_bionic_state ( const bionic_id id)

Get state of bionic with given id.

Definition at line 1784 of file character.cpp.

1785{
1786 for( bionic &b : *my_bionics ) {
1787 if( id == b.id ) {
1788 return b;
1789 }
1790 }
1791 debugmsg( "tried to get state of non-existent bionic with id \"%s\"", id );
1792 std::abort();
1793}

References b, debugmsg, and my_bionics.

Referenced by absorb_hit(), npc::activate_bionic_by_id(), npc::deactivate_bionic_by_id(), and npc::use_bionic_by_id().

◆ get_bionics()

◆ get_cbm_rechargeable_with()

rechargeable_cbm Character::get_cbm_rechargeable_with ( const item it) const

Definition at line 1416 of file consumption.cpp.

1417{
1418 if( can_feed_reactor_with( it ) ) {
1420 }
1421
1422 if( can_feed_furnace_with( it ) ) {
1424 }
1425
1426 if( can_fuel_bionic_with( it ) ) {
1428 }
1429
1431}

References can_feed_furnace_with(), can_feed_reactor_with(), can_fuel_bionic_with(), furnace, none, other, and reactor.

Referenced by can_consume_for_bionic(), and get_acquirable_energy().

◆ get_check_encumbrance()

bool Character::get_check_encumbrance ( )
inline

Definition at line 1986 of file character.h.

1986 {
1987 return check_encumbrance;
1988 }

References check_encumbrance.

Referenced by process_items().

◆ get_consumable_from()

item & Character::get_consumable_from ( item it) const

Returns a reference to the item itself (if it's consumable), the first of its contents (if it's consumable) or null item otherwise.

WARNING: consumable does not necessarily guarantee the comestible type.

Definition at line 1509 of file consumption.cpp.

1510{
1511 if( !it.is_container_empty() && can_consume_as_is( it.contents.front() ) ) {
1512 return it.contents.front();
1513 } else if( can_consume_as_is( it ) ) {
1514 return it;
1515 }
1516
1517 static item null_comestible;
1518 // Since it's not const.
1519 null_comestible = item();
1520 return null_comestible;
1521}

References can_consume_as_is(), item::contents, item_contents::front(), and item::is_container_empty().

Referenced by consume_item(), and find_auto_consume().

◆ get_dependent_worn_items()

std::list< item * > Character::get_dependent_worn_items ( const item it) const

Returns all items that must be taken off before taking off this item.

Definition at line 2396 of file character.cpp.

2397{
2398 std::list<item *> dependent;
2399 // Adds dependent worn items recursively
2400 const std::function<void( const item &it )> add_dependent = [&]( const item & it ) {
2401 for( const item &wit : worn ) {
2402 if( &wit == &it || !wit.is_worn_only_with( it ) ) {
2403 continue;
2404 }
2405 const auto iter = std::find_if( dependent.begin(), dependent.end(),
2406 [&wit]( const item * dit ) {
2407 return &wit == dit;
2408 } );
2409 if( iter == dependent.end() ) { // Not in the list yet
2410 add_dependent( wit );
2411 dependent.push_back( const_cast<item *>( & wit ) );
2412 }
2413 }
2414 };
2415
2416 if( is_worn( it ) ) {
2417 add_dependent( it );
2418 }
2419
2420 return dependent;
2421}

References is_worn(), item::is_worn_only_with(), and worn.

Referenced by can_takeoff(), and pickup::reorder_for_dropping().

◆ get_destination_activity()

player_activity Character::get_destination_activity ( ) const

Definition at line 949 of file character.cpp.

950{
952}

References destination_activity.

Referenced by has_destination_activity(), has_distant_destination(), and start_destination_activity().

◆ get_dex()

◆ get_dex_base()

int Character::get_dex_base ( ) const
virtual

Reimplemented in avatar.

Definition at line 4073 of file character.cpp.

4074{
4075 return dex_max;
4076}

References dex_max.

Referenced by enchantment::activate_passive(), draw_stats_tab(), get_dex(), and avatar::get_dex_base().

◆ get_dex_bonus()

int Character::get_dex_bonus ( ) const
virtual

Definition at line 4090 of file character.cpp.

4091{
4092 return dex_bonus;
4093}

References dex_bonus.

Referenced by reset_stats().

◆ get_dodge()

float Character::get_dodge ( ) const
overridevirtual

Reimplemented from Creature.

Definition at line 809 of file melee.cpp.

810{
811 //If we're asleep or busy we can't dodge
813 return 0.0f;
814 }
815
816 float ret = Creature::get_dodge();
817 // Chop in half if we are unable to move
820 ret /= 2;
821 }
822
823 if( has_effect( effect_grabbed ) ) {
824 int zed_number = 0;
825 for( auto &dest : g->m.points_in_radius( pos(), 1, 0 ) ) {
826 const monster *const mon = g->critter_at<monster>( dest );
827 if( mon && mon->has_effect( effect_grabbing ) ) {
828 zed_number++;
829 }
830 }
831 ret *= 1.0f - ( 0.25f * zed_number );
832 }
833
834 if( worn_with_flag( "ROLLER_INLINE" ) ||
835 worn_with_flag( "ROLLER_QUAD" ) ||
836 worn_with_flag( "ROLLER_ONE" ) ) {
837 ret /= has_trait( trait_PROF_SKATER ) ? 2 : 5;
838 }
839
841 ret /= 4;
842 }
843
844 // Each dodge after the first subtracts equivalent of 2 points of dodge skill
845 if( dodges_left <= 0 ) {
846 ret += dodges_left * 2 - 2;
847 }
848
849 return std::max( 0.0f, ret );
850}
int dodges_left
Definition: character.h:561
virtual float get_dodge() const
Definition: creature.cpp:1514
static const efftype_id effect_lightsnare("lightsnare")
static const efftype_id effect_grabbing("grabbing")
static const efftype_id effect_bouldering("bouldering")
static const efftype_id effect_beartrap("beartrap")
static const efftype_id effect_grabbed("grabbed")
static const efftype_id effect_heavysnare("heavysnare")
static const trait_id trait_PROF_SKATER("PROF_SKATER")

References dodges_left, effect_beartrap, effect_bouldering, effect_grabbed, effect_grabbing, effect_heavysnare, effect_lightsnare, effect_narcosis, g, Creature::get_dodge(), Creature::has_effect(), has_trait(), in_sleep_state(), pos(), cata::hash64_detail::ret, trait_PROF_SKATER, and worn_with_flag().

Referenced by npc::character_danger(), trapfunc::crossbow(), dodge_roll(), draw_skills_tab(), trapfunc::pit(), trapfunc::pit_glass(), trapfunc::pit_spikes(), mattack::science(), trapfunc::shotgun(), and game::update_stair_monsters().

◆ get_dodge_base()

float Character::get_dodge_base ( ) const
overridevirtual

Combat getters.

Dexterity increases dodge base Dodge increases dodge_base

Implements Creature.

Definition at line 5701 of file character.cpp.

5702{
5703 /** @EFFECT_DEX increases dodge base */
5704 /** @EFFECT_DODGE increases dodge_base */
5705 return get_dex() / 2.0f + get_skill_level( skill_dodge );
5706}

References get_dex(), get_skill_level(), and skill_dodge.

◆ get_effective_efficiency()

float Character::get_effective_efficiency ( bionic bio,
float  fuel_efficiency 
)

Applies modifier to fuel_efficiency and returns the resulting efficiency.

Definition at line 1472 of file bionics.cpp.

1473{
1474 const cata::optional<float> &coverage_penalty = bio.info().coverage_power_gen_penalty;
1475 float effective_efficiency = fuel_efficiency;
1476 if( coverage_penalty ) {
1477 int coverage = 0;
1478 const std::map< bodypart_str_id, int > &occupied_bodyparts = bio.info().occupied_bodyparts;
1479 for( const std::pair< const bodypart_str_id, int > &elem : occupied_bodyparts ) {
1480 for( const item &i : worn ) {
1481 if( i.covers( elem.first->token ) && !i.has_flag( flag_ALLOWS_NATURAL_ATTACKS ) &&
1482 !i.has_flag( flag_SEMITANGIBLE ) &&
1483 !i.has_flag( flag_PERSONAL ) && !i.has_flag( flag_AURA ) ) {
1484 coverage += i.get_coverage();
1485 }
1486 }
1487 }
1488 effective_efficiency = fuel_efficiency * ( 1.0 - ( coverage / ( 100.0 *
1489 occupied_bodyparts.size() ) )
1490 * coverage_penalty.value() );
1491 }
1492 return effective_efficiency;
1493}
static const std::string flag_SEMITANGIBLE("SEMITANGIBLE")
static const std::string flag_ALLOWS_NATURAL_ATTACKS("ALLOWS_NATURAL_ATTACKS")
static const std::string flag_AURA("AURA")
static const std::string flag_PERSONAL("PERSONAL")
cata::optional< float > coverage_power_gen_penalty
Fraction of coverage diminishing fuel_efficiency.
Definition: bionics.h:73

References bionic_data::coverage_power_gen_penalty, flag_ALLOWS_NATURAL_ATTACKS(), flag_AURA(), flag_PERSONAL(), flag_SEMITANGIBLE(), bionic::info(), bionic_data::occupied_bodyparts, cata::optional< T >::value(), and worn.

Referenced by burn_fuel(), and passive_power_gen().

◆ get_encumbrance() [1/2]

char_encumbrance_data Character::get_encumbrance ( ) const

Get encumbrance for all body parts.

Definition at line 3668 of file character.cpp.

3669{
3670 return *encumbrance_cache;
3671}

References encumbrance_cache.

Referenced by item::on_wear(), character_display::print_encumbrance(), and should_combine_bps().

◆ get_encumbrance() [2/2]

char_encumbrance_data Character::get_encumbrance ( const item new_item) const

Get encumbrance for all body parts as if new_item was also worn.

Definition at line 3673 of file character.cpp.

3674{
3675 return calc_encumbrance( new_item );
3676}

References calc_encumbrance().

◆ get_env_resist()

int Character::get_env_resist ( bodypart_id  bp) const
overridevirtual

Returns overall env_resist on a body_part.

Reimplemented from Creature.

Definition at line 6987 of file character.cpp.

6988{
6989 int ret = 0;
6990 for( auto &i : worn ) {
6991 // Head protection works on eyes too (e.g. baseball cap)
6992 if( i.covers( bp->token ) || ( bp == bodypart_id( "eyes" ) && i.covers( bp_head ) ) ) {
6993 ret += i.get_env_resist();
6994 }
6995 }
6996
6997 for( const bionic_id &bid : get_bionics() ) {
6998 const auto EP = bid->env_protec.find( bp.id() );
6999 if( ( !bid->activated || has_active_bionic( bid ) ) && EP != bid->env_protec.end() ) {
7000 ret += EP->second;
7001 }
7002 }
7003
7004 if( bp == bodypart_id( "eyes" ) && has_trait( trait_SEESLEEP ) ) {
7005 ret += 8;
7006 }
7007 return ret;
7008}
static const trait_id trait_SEESLEEP("SEESLEEP")

References bp_head, get_bionics(), has_active_bionic(), has_trait(), int_id< T >::id(), cata::hash64_detail::ret, trait_SEESLEEP, and worn.

Referenced by iexamine::flower_poppy(), is_immune_field(), and map::player_in_field().

◆ get_faction()

virtual faction * Character::get_faction ( ) const
inlinevirtual

Reimplemented in avatar, and npc.

Definition at line 360 of file character.h.

360 {
361 return nullptr;
362 }

Referenced by complete_craft(), npc::consume_food_from_camp(), basecamp::faction_display(), and npc::has_faction_relationship().

◆ get_fatigue()

◆ get_fatigue_description()

std::pair< std::string, nc_color > Character::get_fatigue_description ( ) const

Definition at line 4384 of file character.cpp.

4385{
4386 int fatigue = get_fatigue();
4387 std::string fatigue_string;
4388 nc_color fatigue_color = c_white;
4390 fatigue_color = c_red;
4391 fatigue_string = _( "Exhausted" );
4392 } else if( fatigue > fatigue_levels::dead_tired ) {
4393 fatigue_color = c_light_red;
4394 fatigue_string = _( "Dead Tired" );
4395 } else if( fatigue > fatigue_levels::tired ) {
4396 fatigue_color = c_yellow;
4397 fatigue_string = _( "Tired" );
4398 }
4399 return std::make_pair( fatigue_string, fatigue_color );
4400}

References _, c_light_red, c_red, c_white, c_yellow, dead_tired, exhausted, fatigue, get_fatigue(), and tired.

Referenced by draw_health_classic(), draw_needs_compact(), draw_needs_labels(), draw_needs_narrow(), spell::energy_cur_string(), npc::faction_display(), and get_consume_needs_hint().

◆ get_free_bionics_slots()

int Character::get_free_bionics_slots ( const bodypart_id bp) const

Definition at line 2514 of file bionics.cpp.

2515{
2517}
int get_total_bionics_slots(const bodypart_id &bp) const
Definition: bionics.cpp:2509
int get_used_bionics_slots(const bodypart_id &bp) const
Definition: bionics.cpp:2481

References get_total_bionics_slots(), and get_used_bionics_slots().

Referenced by bionic_installation_issues(), and show_bionics_ui().

◆ get_fuel_available()

std::vector< itype_id > Character::get_fuel_available ( const bionic_id bio) const

Return list of available fuel for this bionic.

Definition at line 1994 of file character.cpp.

1995{
1996 std::vector<itype_id> stored_fuels;
1997 for( const itype_id &fuel : bio->fuel_opts ) {
1998 const item tmp_fuel( fuel );
1999 if( !get_value( fuel.str() ).empty() || tmp_fuel.has_flag( flag_PERPETUAL ) ) {
2000 stored_fuels.emplace_back( fuel );
2001 }
2002 }
2003 return stored_fuels;
2004}
static const std::string flag_PERPETUAL("PERPETUAL")

References flag_PERPETUAL(), bionic_data::fuel_opts, Creature::get_value(), item::has_flag(), and string_id< T >::str().

Referenced by burn_fuel(), draw_bionics_titlebar(), passive_power_gen(), process_bionic(), and npc::recharge_cbm().

◆ get_fuel_capacity()

int Character::get_fuel_capacity ( const itype_id fuel) const

Return available space to store specified fuel.

Definition at line 2006 of file character.cpp.

2007{
2008 int amount_stored = 0;
2009 if( !get_value( fuel.str() ).empty() ) {
2010 amount_stored = std::stoi( get_value( fuel.str() ) );
2011 }
2012 int capacity = 0;
2013 for( const bionic_id &bid : get_bionics() ) {
2014 for( const itype_id &fl : bid->fuel_opts ) {
2015 if( get_value( bid.str() ).empty() || get_value( bid.str() ) == fl.str() ) {
2016 if( fl == fuel ) {
2017 capacity += bid->fuel_capacity;
2018 }
2019 }
2020 }
2021 }
2022 return capacity - amount_stored;
2023}

References get_bionics(), Creature::get_value(), and string_id< T >::str().

Referenced by fuel_bionic_with().

◆ get_fueled_bionics()

std::vector< bionic_id > Character::get_fueled_bionics ( ) const

Return bionic_id of fueled bionics.

Definition at line 1861 of file character.cpp.

1862{
1863 std::vector<bionic_id> bionics;
1864 for( const bionic_id &bid : get_bionics() ) {
1865 if( !bid->fuel_opts.empty() ) {
1866 bionics.emplace_back( bid );
1867 }
1868 }
1869 return bionics;
1870}

References get_bionics().

Referenced by npc::recharge_cbm(), and npc::wants_to_recharge_cbm().

◆ get_grammatical_genders()

std::vector< std::string > Character::get_grammatical_genders ( ) const
overridevirtual

Reimplemented from Creature.

Definition at line 5965 of file character.cpp.

5966{
5967 if( male ) {
5968 return { "m" };
5969 } else {
5970 return { "f" };
5971 }
5972}

References male.

Referenced by translate_gendered_line().

◆ get_healthy()

int Character::get_healthy ( ) const
virtual

Getters for health values exclusive to characters.

Definition at line 4129 of file character.cpp.

4130{
4131 return healthy;
4132}

References healthy.

Referenced by debug_menu::character_edit_menu(), eff_fun_fungus(), eff_fun_spores(), expose_to_disease(), hardcoded_effects(), healing_rate(), healing_rate_medicine(), mend(), print_health(), process_one_effect(), and update_health().

◆ get_healthy_mod()

int Character::get_healthy_mod ( ) const
virtual

Definition at line 4133 of file character.cpp.

4134{
4135 return healthy_mod;
4136}

References healthy_mod.

Referenced by debug_menu::character_edit_menu(), process_one_effect(), suffer_from_radiation(), update_health(), and vomit().

◆ get_highest_category()

std::string Character::get_highest_category ( ) const

Returns the highest mutation category.

Returns the mutation category with the highest strength.

Definition at line 7797 of file character.cpp.

7798{
7799 int iLevel = 0;
7800 std::string sMaxCat;
7801
7802 for( const std::pair<const std::string, int> &elem : mutation_category_level ) {
7803 if( elem.second > iLevel ) {
7804 sMaxCat = elem.first;
7805 iLevel = elem.second;
7806 } else if( elem.second == iLevel ) {
7807 sMaxCat.clear(); // no category on ties
7808 }
7809 }
7810 return sMaxCat;
7811}
std::map< std::string, int > mutation_category_level
Definition: character.h:1745

References mutation_category_level.

Referenced by hardcoded_effects(), old_mutate(), map::player_in_field(), and test_crossing_threshold().

◆ get_hit_base()

float Character::get_hit_base ( ) const
overridevirtual
Dexterity increases hit base, slightly

Implements Creature.

Definition at line 5707 of file character.cpp.

5708{
5709 /** @EFFECT_DEX increases hit base, slightly */
5710 return get_dex() / 4.0f;
5711}

References get_dex().

Referenced by get_melee_hit_base().

◆ get_hit_weapon()

float Character::get_hit_weapon ( const item weap) const

Gets melee accuracy component from weapon+skills.

Unarmed improves hit chance for unarmed weapons Bashing improves hit chance for bashing weapons Cutting improves hit chance for cutting weapons Stabbing improves hit chance for piercing weapons Melee improves hit chance for all items (including non-weapons)

Definition at line 277 of file melee.cpp.

278{
279 /** @EFFECT_UNARMED improves hit chance for unarmed weapons */
280 /** @EFFECT_BASHING improves hit chance for bashing weapons */
281 /** @EFFECT_CUTTING improves hit chance for cutting weapons */
282 /** @EFFECT_STABBING improves hit chance for piercing weapons */
283 auto skill = get_skill_level( weap.melee_skill() );
284
285 // CQB bionic acts as a lower bound providing item uses a weapon skill
286 if( skill < BIO_CQB_LEVEL && has_active_bionic( bio_cqb ) ) {
287 skill = BIO_CQB_LEVEL;
288 }
289
290 /** @EFFECT_MELEE improves hit chance for all items (including non-weapons) */
291 return ( skill / 3.0f ) + ( get_skill_level( skill_melee ) / 2.0f ) + weap.type->m_to_hit;
292}

References bio_cqb, BIO_CQB_LEVEL, get_skill_level(), has_active_bionic(), itype::m_to_hit, item::melee_skill(), skill_melee, and item::type.

Referenced by item::effective_dps(), and get_melee_hit_base().

◆ get_hostile_creatures()

std::vector< Creature * > Character::get_hostile_creatures ( int  range) const

Get all hostile creatures currently visible to this player.

Definition at line 10191 of file character.cpp.

10192{
10193 return g->get_creatures_if( [this, range]( const Creature & critter ) -> bool {
10194 // Fixes circular distance range for ranged attacks
10195 float dist_to_creature = std::round( rl_dist_exact( pos(), critter.pos() ) );
10196 return this != &critter && pos() != critter.pos() && // TODO: get rid of fake npcs (pos() check)
10197 dist_to_creature <= range && critter.attitude_to( *this ) == A_HOSTILE
10198 && sees( critter );
10199 } );
10200}
virtual Attitude attitude_to(const Creature &other) const =0
Attitude (of this creature) towards another creature.
float rl_dist_exact(const tripoint &loc1, const tripoint &loc2)
Definition: line.cpp:292

References Creature::A_HOSTILE, Creature::attitude_to(), g, Creature::pos(), pos(), rl_dist_exact(), and sees().

◆ get_hunger_description()

std::pair< std::string, nc_color > Character::get_hunger_description ( ) const

Definition at line 4349 of file character.cpp.

4350{
4351 int total_kcal = stored_calories + stomach.get_calories();
4352 int max_kcal = max_stored_kcal();
4353 float days_left = static_cast<float>( total_kcal ) / bmr();
4354 float days_max = static_cast<float>( max_kcal ) / bmr();
4355 std::string hunger_string;
4356 nc_color hunger_color = c_white;
4357 if( days_left >= days_max ) {
4358 hunger_string = _( "Engorged" );
4359 hunger_color = c_green;
4360 } else if( days_max - days_left < 0.5f ) {
4361 hunger_string = _( "Sated" );
4362 hunger_color = c_green;
4363 } else if( days_max - days_left < 1.0f ) {
4364 hunger_string = _( "Hungry" );
4365 hunger_color = c_yellow;
4366 } else if( days_max / days_left < 2.0f ) {
4367 hunger_string = _( "Very Hungry" );
4368 hunger_color = c_yellow;
4369 } else if( days_left > 1 ) {
4370 hunger_string = _( "Famished" );
4371 hunger_color = c_light_red;
4372 } else {
4373 hunger_string = _( "Starving" );
4374 hunger_color = c_red;
4375 }
4376
4377 if( has_trait( trait_SELFAWARE ) ) {
4378 hunger_string = string_format( "%d kcal", total_kcal );
4379 }
4380
4381 return std::make_pair( hunger_string, hunger_color );
4382}
static const trait_id trait_SELFAWARE("SELFAWARE")

References _, bmr(), c_green, c_light_red, c_red, c_white, c_yellow, stomach_contents::get_calories(), has_trait(), max_stored_kcal(), stomach, stored_calories, string_format(), and trait_SELFAWARE.

Referenced by draw_health_classic(), draw_needs_compact(), draw_needs_labels(), draw_needs_narrow(), npc::faction_display(), and get_consume_needs_hint().

◆ get_int()

◆ get_int_base()

int Character::get_int_base ( ) const
virtual

Reimplemented in avatar.

Definition at line 4081 of file character.cpp.

4082{
4083 return int_max;
4084}

References int_max.

Referenced by enchantment::activate_passive(), draw_stats_tab(), get_int(), and avatar::get_int_base().

◆ get_int_bonus()

int Character::get_int_bonus ( ) const
virtual

Definition at line 4098 of file character.cpp.

4099{
4100 return int_bonus;
4101}

References int_bonus.

Referenced by reset_stats().

◆ get_item_position()

int Character::get_item_position ( const item it) const

Returns the item position (suitable for i_at or similar) of a specific item.

Returns INT_MIN if the item is not found. Note that this may lose some information, for example the returned position is the same when the given item points to the container and when it points to the item inside the container. All items that are part of the same stack have the same item position.

Definition at line 2325 of file character.cpp.

2326{
2327 if( weapon.has_item( *it ) ) {
2328 return -1;
2329 }
2330
2331 int p = 0;
2332 for( const auto &e : worn ) {
2333 if( e.has_item( *it ) ) {
2334 return worn_position_to_index( p );
2335 }
2336 p++;
2337 }
2338
2339 return inv.position_by_item( it );
2340}
static int worn_position_to_index(int position)
Definition: character.h:1081
bool has_item(const item &it) const
Returns true if this visitable instance contains the item.
Definition: visitable.cpp:95

References visitable< T >::has_item(), inv, inventory::position_by_item(), weapon, worn, and worn_position_to_index().

Referenced by npc::alt_attack(), game::butcher(), iuse::chop_logs(), iuse::chop_tree(), chop_tree_activity(), convert_to_items(), damage_item(), iuse::fill_pit(), iuse::hacksaw(), monexamine::insert_battery(), iuse::makemound(), item_location::impl::item_on_person::obtain(), iuse::pack_item(), iuse::play_game(), iuse::radglove(), iuse::stimpack(), salvage_actor::try_to_cut_up(), pick_lock_actor::use(), musical_instrument_actor::use(), repair_item_actor::use(), sew_advanced_actor::use(), and avatar_action::wield().

◆ get_kcal_percent()

◆ get_learned_recipes()

const recipe_subset & Character::get_learned_recipes ( ) const

Returns all known recipes.

Definition at line 10536 of file character.cpp.

10537{
10538 if( *_skills != *autolearn_skills_stamp ) {
10539 for( const auto &r : recipe_dict.all_autolearn() ) {
10540 if( meets_skill_requirements( r->autolearn_requirements ) ) {
10541 learned_recipes->include( r );
10542 }
10543 }
10545 }
10546
10547 return *learned_recipes;
10548}
pimpl< recipe_subset > learned_recipes
Subset of learned recipes.
Definition: character.h:2145
pimpl< SkillLevelMap > autolearn_skills_stamp
Stamp of character skills.
Definition: character.h:2143
const std::set< const recipe * > & all_autolearn() const
Returns all recipes that can be automatically learned.

References _skills, recipe_dictionary::all_autolearn(), autolearn_skills_stamp, learned_recipes, meets_skill_requirements(), and recipe_dict.

Referenced by player::get_available_recipes(), knows_recipe(), peek_related_recipe(), and select_crafting_recipe().

◆ get_lowest_hp()

int Character::get_lowest_hp ( ) const

Definition at line 10330 of file character.cpp.

10331{
10332 // Set lowest_hp to an arbitrarily large number.
10333 int lowest_hp = 999;
10334 for( const std::pair<const bodypart_str_id, bodypart> &elem : get_body() ) {
10335 const int cur_hp = elem.second.get_hp_cur();
10336 if( cur_hp < lowest_hp ) {
10337 lowest_hp = cur_hp;
10338 }
10339 }
10340 return lowest_hp;
10341}

References Creature::get_body().

Referenced by debug_menu::character_edit_menu().

◆ get_max_healthy()

int Character::get_max_healthy ( ) const

Definition at line 4531 of file character.cpp.

4532{
4533 return 200;
4534}

Referenced by update_health().

◆ get_max_power_level()

◆ get_melee()

float Character::get_melee ( ) const
overridevirtual

Returns melee skill level, to be used to throttle dodge practice.

Implements Creature.

Definition at line 857 of file melee.cpp.

858{
859 return get_skill_level( skill_id( "melee" ) );
860}

References get_skill_level(), and skill_id.

Referenced by stability_roll().

◆ get_melee_hit_base()

float Character::get_melee_hit_base ( ) const

Returns weapon skill.

Definition at line 294 of file melee.cpp.

295{
296 // Character::get_hit_base includes stat calculations already
298}
const item & used_weapon() const
Returns a reference to the item which will be used to make attacks.
Definition: melee.cpp:138
float get_hit_weapon(const item &weap) const
Gets melee accuracy component from weapon+skills.
Definition: melee.cpp:277
float get_hit_base() const override
Definition: character.cpp:5707
float mabuff_tohit_bonus() const
Returns the to hit bonus from martial arts buffs.

References get_hit_base(), get_hit_weapon(), mabuff_tohit_bonus(), and used_weapon().

Referenced by draw_stats_info(), hit_roll(), and set_stats().

◆ get_miss_reason()

std::string Character::get_miss_reason ( )

Returns an explanation for why the player would miss a melee attack.

Definition at line 332 of file melee.cpp.

333{
334 // everything that lowers accuracy in player::hit_roll()
335 // adding it in hit_roll() might not be safe if it's called multiple times
336 // in one turn
338 _( "Your torso encumbrance throws you off-balance." ),
339 roll_remainder( encumb( bp_torso ) / 10.0 ) );
340 const int farsightedness = 2 * ( has_trait( trait_HYPEROPIC ) &&
341 !worn_with_flag( "FIX_FARSIGHT" ) &&
344 _( "You can't hit reliably due to your farsightedness." ),
345 farsightedness );
346
347 const std::string *const reason = melee_miss_reasons.pick();
348 if( reason == nullptr ) {
349 return std::string();
350 }
351 return *reason;
352}
void add_miss_reason(const std::string &reason, unsigned int weight)
Adds a reason for why the player would miss a melee attack.
Definition: melee.cpp:321
static const efftype_id effect_contacts("contacts")
static const trait_id trait_HYPEROPIC("HYPEROPIC")

References _, add_miss_reason(), bp_torso, effect_contacts, encumb(), Creature::has_effect(), has_trait(), melee_miss_reasons, roll_remainder(), trait_HYPEROPIC, and worn_with_flag().

Referenced by melee_attack().

◆ get_mod()

int Character::get_mod ( const trait_id mut,
const std::string &  arg 
) const
private

Retrieves a stat mod of a mutation.

Definition at line 195 of file mutation.cpp.

196{
197 auto &mod_data = mut->mods;
198 int ret = 0;
199 auto found = mod_data.find( std::make_pair( false, arg ) );
200 if( found != mod_data.end() ) {
201 ret += found->second;
202 }
203 return ret;
204}
detail::named_arg< Char, T > arg(const Char *name, const T &arg)
\rst Returns a named argument to be used in a formatting function.
Definition: fmtlib_core.h:1860
std::unordered_map< std::pair< bool, std::string >, int, cata::tuple_hash > mods
Key pair is <active: bool, mod type: "STR">
Definition: mutation.h:275

References arg(), mutation_branch::mods, and cata::hash64_detail::ret.

Referenced by apply_mods().

◆ get_mod_stat_from_bionic()

int Character::get_mod_stat_from_bionic ( const character_stat Stat) const

Get stat bonus from bionic.

Definition at line 2087 of file character.cpp.

2088{
2089 int ret = 0;
2090 for( const bionic_id &bid : get_bionics() ) {
2091 const auto St_bn = bid->stat_bonus.find( Stat );
2092 if( St_bn != bid->stat_bonus.end() ) {
2093 ret += St_bn->second;
2094 }
2095 }
2096 return ret;
2097}

References get_bionics(), and cata::hash64_detail::ret.

Referenced by reset_stats().

◆ get_morale()

int Character::get_morale ( const morale_type type) const

Definition at line 9063 of file character.cpp.

9064{
9065 return morale->get( type );
9066}

References morale, and type.

◆ get_morale_level()

int Character::get_morale_level ( ) const

◆ get_most_efficient_bionic()

bionic_id Character::get_most_efficient_bionic ( const std::vector< bionic_id > &  bids) const

Return bionic_id of bionic of most fuel efficient bionic.

Definition at line 1872 of file character.cpp.

1873{
1874 float temp_eff = 0;
1875 bionic_id bio( "null" );
1876 for( const bionic_id &bid : bids ) {
1877 if( bid->fuel_efficiency > temp_eff ) {
1878 temp_eff = bid->fuel_efficiency;
1879 bio = bid;
1880 }
1881 }
1882 return bio;
1883}

Referenced by fuel_bionic_with(), and get_acquirable_energy().

◆ get_movement_mode()

character_movemode Character::get_movement_mode ( ) const

Definition at line 1535 of file character.cpp.

1536{
1537 return move_mode;
1538}

References move_mode.

Referenced by cata_event_dispatch::avatar_moves().

◆ get_mutation_social_mods()

social_modifiers Character::get_mutation_social_mods ( ) const

Goes over all mutations, returning the sum of the social modifiers.

Definition at line 6522 of file character.cpp.

6523{
6524 social_modifiers mods;
6525 for( const mutation_branch *mut : cached_mutations ) {
6526 mods += mut->social_mods;
6527 }
6528
6529 return mods;
6530}

References cached_mutations.

Referenced by talk_trial::calc_chance().

◆ get_mutations()

std::vector< trait_id > Character::get_mutations ( bool  include_hidden = true) const

Get the idents of all traits/mutations.

Definition at line 2857 of file newcharacter.cpp.

2858{
2859 std::vector<trait_id> result;
2860 for( const std::pair<const trait_id, char_trait_data> &t : my_mutations ) {
2861 if( include_hidden || t.first.obj().player_display ) {
2862 result.push_back( t.first );
2863 }
2864 }
2865 for( const trait_id &ench_trait : enchantment_cache->get_mutations() ) {
2866 if( include_hidden || ench_trait->player_display ) {
2867 bool found = false;
2868 for( const trait_id &exist : result ) {
2869 if( exist == ench_trait ) {
2870 found = true;
2871 break;
2872 }
2873 }
2874 if( !found ) {
2875 result.push_back( ench_trait );
2876 }
2877 }
2878 }
2879 return result;
2880}

References enchantment_cache, and my_mutations.

Referenced by monster::attitude(), bodytemp_modifier_traits(), bodytemp_modifier_traits_floor(), can_eat(), can_install_cbm_on_bp(), can_use_heal_item(), can_wear(), check_and_recover_morale(), compute_default_effective_vitamins(), player::crafting_success_roll(), avatar::create(), crossed_threshold(), character_display::disp_info(), drench_mut_calc(), npc::form_opinion(), has_trait_flag(), is_category_allowed(), is_weak_to_water(), mod_healthy(), mut_cbm_encumb(), mutation_armor(), mutation_attacks(), item::mutations_from_wearing(), diary::new_page(), process_turn(), avatar::randomize(), reset_scenario(), roll_bash_damage(), roll_cut_damage(), roll_stab_damage(), set_description(), set_highest_cat_level(), set_profession(), sleep(), update_type_of_scent(), visible_mutations(), vitamin_rate(), and memorial_logger::write().

◆ get_name()

std::string Character::get_name ( ) const
overridevirtual

Implements Creature.

Definition at line 5960 of file character.cpp.

5961{
5962 return name;
5963}

References name.

Referenced by apply_damage(), autodoc_internal(), debug_menu::character_edit_menu(), npc::die(), pour_into(), npc::set_omt_destination(), and game::vertical_move().

◆ get_next_auto_move_direction()

action_id Character::get_next_auto_move_direction ( )

Definition at line 10493 of file character.cpp.

10494{
10495 if( !has_destination() ) {
10496 return ACTION_NULL;
10497 }
10498
10500 if( pos() != *next_expected_position ) {
10501 // We're off course, possibly stumbling or stuck, cancel auto move
10502 return ACTION_NULL;
10503 }
10504 }
10505
10506 next_expected_position.emplace( auto_move_route.front() );
10507 auto_move_route.erase( auto_move_route.begin() );
10508
10510
10511 // Make sure the direction is just one step and that
10512 // all diagonal moves have 0 z component
10513 if( std::abs( dp.x ) > 1 || std::abs( dp.y ) > 1 || std::abs( dp.z ) > 1 ||
10514 ( std::abs( dp.z ) != 0 && ( std::abs( dp.x ) != 0 || std::abs( dp.y ) != 0 ) ) ) {
10515 // Should never happen, but check just in case
10516 return ACTION_NULL;
10517 }
10519}
action_id get_movement_action_from_delta(const tripoint &d, const iso_rotate rot)
Translate coordinate delta into movement action.
Definition: action.cpp:484
@ ACTION_NULL
Invalid action used for various lookup errors.
Definition: action.h:24
int y
Definition: point.h:151
int z
Definition: point.h:152
int x
Definition: point.h:150

References ACTION_NULL, auto_move_route, get_movement_action_from_delta(), has_destination(), next_expected_position, pos(), tripoint::x, tripoint::y, yes, and tripoint::z.

Referenced by game::handle_action(), and game::try_get_left_click_action().

◆ get_npc_ai_info_cache()

cata::optional< double > Character::get_npc_ai_info_cache ( const std::string &  key) const

Definition at line 10593 of file character.cpp.

10594{
10595 auto it = npc_ai_info_cache.find( key );
10596 if( it == npc_ai_info_cache.end() ) {
10597 return cata::nullopt;
10598 } else {
10599 return it->second;
10600 }
10601}

References npc_ai_info_cache, and cata::nullopt.

Referenced by npc::find_reloadable(), and npc_ai::weapon_value().

◆ get_overlay_ids()

std::vector< std::string > Character::get_overlay_ids ( ) const

Returns a list of the IDs of overlays on this character, sorted from "lowest" to "highest".

Only required for rendering.

Definition at line 3252 of file character.cpp.

3253{
3254 std::vector<std::string> rval;
3255 std::multimap<int, std::string> mutation_sorting;
3256 int order;
3257 std::string overlay_id;
3258
3259 // first get effects
3260 for( const auto &eff_pr : *effects ) {
3261 if( !eff_pr.second.begin()->second.is_removed() ) {
3262 rval.push_back( "effect_" + eff_pr.first.str() );
3263 }
3264 }
3265
3266 // then get mutations
3267 for( const std::pair<const trait_id, char_trait_data> &mut : my_mutations ) {
3268 overlay_id = ( mut.second.powered ? "active_" : "" ) + mut.first.str();
3269 order = get_overlay_order_of_mutation( overlay_id );
3270 mutation_sorting.insert( std::pair<int, std::string>( order, overlay_id ) );
3271 }
3272
3273 // then get bionics
3274 for( const bionic &bio : *my_bionics ) {
3275 overlay_id = ( bio.powered ? "active_" : "" ) + bio.id.str();
3276 order = get_overlay_order_of_mutation( overlay_id );
3277 mutation_sorting.insert( std::pair<int, std::string>( order, overlay_id ) );
3278 }
3279
3280 for( auto &mutorder : mutation_sorting ) {
3281 rval.push_back( "mutation_" + mutorder.second );
3282 }
3283
3284 // next clothing
3285 // TODO: worry about correct order of clothing overlays
3286 for( const item &worn_item : worn ) {
3287 rval.push_back( "worn_" + worn_item.typeId().str() );
3288 }
3289
3290 // last weapon
3291 // TODO: might there be clothing that covers the weapon?
3292 if( is_armed() ) {
3293 rval.push_back( "wielded_" + weapon.typeId().str() );
3294 }
3295
3296 if( move_mode != CMM_WALK ) {
3297 rval.push_back( io::enum_to_string( move_mode ) );
3298 }
3299 return rval;
3300}
std::string enum_to_string(E)
int get_overlay_order_of_mutation(const std::string &mutation_id_string)

References CMM_WALK, Creature::effects, io::enum_to_string(), get_overlay_order_of_mutation(), is_armed(), move_mode, my_bionics, my_mutations, string_id< T >::str(), item::typeId(), weapon, and worn.

◆ get_pain_description()

std::pair< std::string, nc_color > Character::get_pain_description ( ) const
overridevirtual

Reimplemented from Creature.

Definition at line 4453 of file character.cpp.

4454{
4455 const std::pair<std::string, nc_color> pain = Creature::get_pain_description();
4456 nc_color pain_color = pain.second;
4457 std::string pain_string;
4458 // get pain color
4459 if( get_perceived_pain() >= 60 ) {
4460 pain_color = c_red;
4461 } else if( get_perceived_pain() >= 40 ) {
4462 pain_color = c_light_red;
4463 }
4464 // get pain string
4466 get_perceived_pain() > 0 ) {
4467 pain_string = string_format( "%s %d", _( "Pain " ), get_perceived_pain() );
4468 } else if( get_perceived_pain() > 0 ) {
4469 pain_string = pain.first;
4470 }
4471 return std::make_pair( pain_string, pain_color );
4472}
static const efftype_id effect_got_checked("got_checked")
virtual std::pair< std::string, nc_color > get_pain_description() const
Definition: creature.cpp:1382
int pain
Definition: creature.h:892

References _, c_light_red, c_red, effect_got_checked, Creature::get_pain_description(), get_perceived_pain(), Creature::has_effect(), has_trait(), Creature::pain, string_format(), and trait_SELFAWARE.

Referenced by draw_health_classic(), draw_needs_compact(), draw_needs_labels(), draw_needs_narrow(), and get_consume_needs_hint().

◆ get_painkiller()

int Character::get_painkiller ( ) const

◆ get_path_avoid()

std::set< tripoint > Character::get_path_avoid ( ) const
overridevirtual

Returns a set of points we do not want to path through.

Implements Creature.

Reimplemented in npc.

Definition at line 9907 of file character.cpp.

9908{
9909 std::set<tripoint> ret;
9910 for( npc &guy : g->all_npcs() ) {
9911 if( sees( guy ) ) {
9912 ret.insert( guy.pos() );
9913 }
9914 }
9915
9916 // TODO: Add known traps in a way that doesn't destroy performance
9917
9918 return ret;
9919}

References g, cata::hash64_detail::ret, and sees().

Referenced by activity_on_turn_move_loot(), can_mount(), game::handle_action(), game::list_items(), game::look_around(), perform_zone_activity_turn(), route_adjacent(), activity_handlers::travel_do_turn(), and game::try_get_left_click_action().

◆ get_pathfinding_settings()

const pathfinding_settings & Character::get_pathfinding_settings ( ) const
overridevirtual

◆ get_per()

◆ get_per_base()

int Character::get_per_base ( ) const
virtual

Reimplemented in avatar.

Definition at line 4077 of file character.cpp.

4078{
4079 return per_max;
4080}

References per_max.

Referenced by enchantment::activate_passive(), draw_stats_tab(), get_per(), and avatar::get_per_base().

◆ get_per_bonus()

int Character::get_per_bonus ( ) const
virtual

Definition at line 4094 of file character.cpp.

4095{
4096 return per_bonus;
4097}

References per_bonus.

Referenced by reset_stats().

◆ get_perceived_pain()

int Character::get_perceived_pain ( ) const
overridevirtual

◆ get_power_level()

◆ get_rad()

◆ get_remote_fueled_bionic()

bionic_id Character::get_remote_fueled_bionic ( ) const

Returns bionic_id of first remote fueled bionic found.

Definition at line 1820 of file character.cpp.

1821{
1822 for( const bionic_id &bid : get_bionics() ) {
1823 if( bid->is_remote_fueled ) {
1824 return bid;
1825 }
1826 }
1827 return bionic_id();
1828}

References bionic_id, and get_bionics().

Referenced by iuse::cable_attach(), and iuse::solarpack().

◆ get_safe_reference()

safe_reference< Character > Character::get_safe_reference ( )

Definition at line 10875 of file character.cpp.

10876{
10877 return anchor.reference_to( this );
10878}
safe_reference_anchor anchor
Definition: character.h:2246
safe_reference< T > reference_to(T *object)

References anchor, and safe_reference_anchor::reference_to().

Referenced by itype::invoke().

◆ get_shout_volume()

int Character::get_shout_volume ( ) const
Strength increases shouting volume

Definition at line 7546 of file character.cpp.

7547{
7548 int base = 10;
7549 int shout_multiplier = 2;
7550
7551 // Mutations make shouting louder, they also define the default message
7552 if( has_trait( trait_SHOUT3 ) ) {
7553 shout_multiplier = 4;
7554 base = 20;
7555 } else if( has_trait( trait_SHOUT2 ) ) {
7556 base = 15;
7557 shout_multiplier = 3;
7558 }
7559
7560 // You can't shout without your face
7561 if( has_trait( trait_PROF_FOODP ) && !( is_wearing( itype_id( "foodperson_mask" ) ) ||
7562 is_wearing( itype_id( "foodperson_mask_on" ) ) ) ) {
7563 base = 0;
7564 shout_multiplier = 0;
7565 }
7566
7567 // Masks and such dampen the sound
7568 // Balanced around whisper for wearing bondage mask
7569 // and noise ~= 10 (door smashing) for wearing dust mask for character with strength = 8
7570 /** @EFFECT_STR increases shouting volume */
7571 const int penalty = encumb( bp_mouth ) * 3 / 2;
7572 int noise = base + str_cur * shout_multiplier - penalty;
7573
7574 // Minimum noise volume possible after all reductions.
7575 // Volume 1 can't be heard even by player
7576 constexpr int minimum_noise = 2;
7577
7578 if( noise <= base ) {
7579 noise = std::max( minimum_noise, noise );
7580 }
7581
7582 // Screaming underwater is not good for oxygen and harder to do overall
7583 if( is_underwater() ) {
7584 noise = std::max( minimum_noise, noise / 2 );
7585 }
7586 return noise;
7587}
static const trait_id trait_SHOUT2("SHOUT2")
static const trait_id trait_SHOUT3("SHOUT3")

References bp_mouth, encumb(), has_trait(), Creature::is_underwater(), is_wearing(), itype_id, noise, str_cur, trait_PROF_FOODP, trait_SHOUT2, and trait_SHOUT3.

Referenced by game::chat(), npc::say(), shout(), and activity_handlers::spellcasting_finish().

◆ get_size()

◆ get_skill_level() [1/2]

int Character::get_skill_level ( const skill_id ident) const

Definition at line 3317 of file character.cpp.

3318{
3319 return _skills->get_skill_level( ident );
3320}

References _skills.

Referenced by npc::address_needs(), ranged::aim_speed_skill_modifier(), apply_skill_boost(), iexamine::arcfurnace_empty(), attack_cost(), avoid_trap(), mattack::bio_op_disarm(), bionics_pl_skill(), block_hit(), item::book_info(), ranged::burst_penalty(), activity_handlers::butcher_finish(), calc_skill_training_cost(), calc_skill_training_time(), veh_utils::calc_xp_gain(), character_martial_arts::can_arm_block(), can_autolearn_martial_art(), can_estimate_rot(), character_martial_arts::can_leg_block(), can_mount(), npc::can_read(), enzlave_actor::can_use(), caravan_price(), activity_handlers::chop_planks_finish(), item::color_in_inventory(), companion_combat_rank(), companion_industry_rank(), companion_survival_rank(), complete_craft(), crafting::complete_disassemble(), construction_color(), player::crafting_success_roll(), crit_chance(), iuse::crowbar(), salvage_actor::cut_up(), mattack::dermatik(), trap::detect_trap(), avatar::do_read(), dialogue::dynamic_line(), iuse::einktabletpc(), enumerate_unmet_requirements(), spell::exp_modifier(), map_data_common_t::extended_description(), npc::faction_display(), fall_damage_mod(), farm_action(), game::find_or_make_stairs(), npc::finish_read(), activity_handlers::fish_do_turn(), iuse::fish_trap(), item::food_info(), fungal_effects::fungalize(), player::get_available_recipes(), item::get_available_recipes(), heal_actor::get_bandaged_level(), avatar::get_book_reader(), heal_actor::get_disinfected_level(), get_dodge_base(), get_encumbrance_description(), heal_actor::get_heal_value(), get_hit_weapon(), get_melee(), player_activity::get_progress_message(), ranged::get_weapon_dispersion(), iuse::gun_repair(), npc_ai::gun_value(), avatar_funcs::gunmod_installation_odds(), computer_session::hack_attempt(), hack_level(), hackveh(), handle_melee_wear(), hardcoded_mutation_attack(), harvest_common(), iexamine::harvest_plant(), has_skill_for_vehicle_work(), ma_requirements::is_valid_character(), item_reload_cost(), item_store_cost(), ma_style_callback::key(), iexamine::kiln_empty(), activity_handlers::lockpicking_finish(), melee_attack(), avatar_funcs::mend_item(), iuse::mind_splicer(), morale_crafting_speed_multiplier(), iuse::multicooker(), mutation_attacks(), npc_trading::net_price_adjustment(), game::npc_menu(), on_dodge(), item::on_wield(), iuse::pack_cbm(), monexamine::pet_menu(), pick_part_to_heal(), pick_plant(), vehicle::pldrive(), practice(), iexamine::practice_survival_while_foraging(), mattack::pull_metal_weapon(), activity_handlers::pulp_do_turn(), avatar::randomize(), examine_item_menu::rate_action_use(), reach_attack(), avatar::read(), recalc_hp(), repair_item_actor::repair(), repair_item_actor::repair_chance(), activity_handlers::repair_item_finish(), activity_handlers::robot_control_finish(), iuse::robotcontrol(), roll_bash_damage(), roll_cut_damage(), roll_stab_damage(), iexamine::safe(), scavenging_combat_skill(), set_description(), conditional_t< T >::set_has_skill(), set_skills(), map::shake_vehicle(), iexamine::shrub_wildveggies(), sinkhole_safety_roll(), skill_increment_cost(), npc::skills_offered_to(), smash(), read_inventory_preset::sort_compare(), spell::spell_fail(), player::start_craft(), talk_function::start_training(), suffer_from_schizophrenia(), survive_random_encounter(), swim_speed(), character_effects::talk_skill(), iuse::tazer(), ranged::throw_item(), throw_range(), mattack::thrown_by_judo(), time_to_attack(), known_magic::time_to_learn_spell(), npc::time_to_read(), avatar::time_to_read(), item::tname(), activity_handlers::train_finish(), iexamine::tree_hickory(), avatar_funcs::try_disarm_npc(), character_funcs::try_wield_contents(), veh_interact::update_part_requirements(), place_monster_iuse::use(), firestarter_actor::use(), enzlave_actor::use(), heal_actor::use(), sew_advanced_actor::use(), npc::value(), game::vertical_move(), and debug_menu::wishskill().

◆ get_skill_level() [2/2]

int Character::get_skill_level ( const skill_id ident,
const item context 
) const

Definition at line 3322 of file character.cpp.

3323{
3324 return _skills->get_skill_level( ident, context );
3325}

References _skills.

◆ get_skill_level_object() [1/2]

◆ get_skill_level_object() [2/2]

const SkillLevel & Character::get_skill_level_object ( const skill_id ident) const

Definition at line 3307 of file character.cpp.

3308{
3309 return _skills->get_skill_level_object( ident );
3310}

References _skills.

◆ get_sleep_deprivation()

int Character::get_sleep_deprivation ( ) const

Definition at line 4448 of file character.cpp.

4449{
4450 return sleep_deprivation;
4451}

References sleep_deprivation.

Referenced by debug_menu::character_edit_menu(), check_needs_extremes(), hardcoded_effects(), reset_stats(), and suffer().

◆ get_speed()

◆ get_stamina()

◆ get_stamina_max()

int Character::get_stamina_max ( ) const

Definition at line 7053 of file character.cpp.

7054{
7055 static const std::string player_max_stamina( "PLAYER_MAX_STAMINA" );
7056 static const std::string max_stamina_modifier( "max_stamina_modifier" );
7057 const int baseMaxStamina = get_option< int >( player_max_stamina );
7058 int maxStamina = baseMaxStamina;
7059 maxStamina *= Character::mutation_value( max_stamina_modifier );
7060 maxStamina += bonus_from_enchantments( maxStamina, enchant_vals::mod::STAMINA_CAP );
7061 return std::max( baseMaxStamina / 10, maxStamina );
7062}

References bonus_from_enchantments(), mutation_value(), and enchant_vals::STAMINA_CAP.

Referenced by attack_cost(), block_hit(), can_run(), debug_menu::character_edit_menu(), cough(), player_activity::do_turn(), draw_char_narrow(), draw_char_wide(), draw_health_classic(), draw_limb2(), spell::energy_cost_string(), spell::energy_cur_string(), aim_activity_actor::load_RAS_weapon(), mod_stamina(), character_funcs::normalize(), on_dodge(), on_item_takeoff(), on_item_wear(), npc::process_turn(), activity_handlers::pulp_do_turn(), avatar::read(), speed_rating(), stamina_move_cost_modifier(), game::start_game(), iuse::stimpack(), update_stamina(), activity_handlers::wait_stamina_do_turn(), and activity_handlers::wait_stamina_finish().

◆ get_stashed_activity()

player_activity Character::get_stashed_activity ( ) const

Definition at line 894 of file character.cpp.

895{
897}

References stashed_outbounds_activity.

Referenced by npc::move().

◆ get_stim()

◆ get_stored_kcal()

◆ get_str()

◆ get_str_base()

int Character::get_str_base ( ) const
virtual

Reimplemented in avatar.

Definition at line 4069 of file character.cpp.

4070{
4071 return str_max;
4072}

References str_max.

Referenced by enchantment::activate_passive(), draw_stats_tab(), get_str(), avatar::get_str_base(), and recalc_hp().

◆ get_str_bonus()

int Character::get_str_bonus ( ) const
virtual

Definition at line 4086 of file character.cpp.

4087{
4088 return str_bonus;
4089}

References str_bonus.

Referenced by reset_stats().

◆ get_thirst()

◆ get_thirst_description()

std::pair< std::string, nc_color > Character::get_thirst_description ( ) const

Definition at line 4320 of file character.cpp.

4321{
4322 int thirst = get_thirst();
4323 std::string hydration_string;
4324 nc_color hydration_color = c_white;
4326 hydration_color = c_light_red;
4327 hydration_string = _( "Parched" );
4328 } else if( thirst > thirst_levels::dehydrated ) {
4329 hydration_color = c_light_red;
4330 hydration_string = _( "Dehydrated" );
4331 } else if( thirst > thirst_levels::very_thirsty ) {
4332 hydration_color = c_yellow;
4333 hydration_string = _( "Very thirsty" );
4334 } else if( thirst > thirst_levels::thirsty ) {
4335 hydration_color = c_yellow;
4336 hydration_string = _( "Thirsty" );
4337 } else if( thirst > thirst_levels::slaked ) {
4338 // Nothing
4339 } else if( thirst > thirst_levels::hydrated ) {
4340 hydration_color = c_green;
4341 hydration_string = _( "Hydrated" );
4342 } else if( thirst > thirst_levels::turgid ) {
4343 hydration_color = c_green;
4344 hydration_string = _( "Turgid" );
4345 }
4346 return std::make_pair( hydration_string, hydration_color );
4347}

References _, c_green, c_light_red, c_white, c_yellow, dehydrated, get_thirst(), hydrated, parched, slaked, thirst, thirsty, turgid, and very_thirsty.

Referenced by draw_health_classic(), draw_needs_compact(), draw_needs_labels(), draw_needs_narrow(), npc::faction_display(), and get_consume_needs_hint().

◆ get_time_died()

time_point Character::get_time_died ( ) const
inline

return the calendar::turn the character expired

Definition at line 1438 of file character.h.

1438 {
1439 return time_died;
1440 }
time_point time_died
Definition: character.h:2155

References time_died.

◆ get_total_bionics_slots()

int Character::get_total_bionics_slots ( const bodypart_id bp) const

Definition at line 2509 of file bionics.cpp.

2510{
2511 return bp->bionic_slots();
2512}

Referenced by get_free_bionics_slots(), and show_bionics_ui().

◆ get_total_fuel_capacity()

int Character::get_total_fuel_capacity ( const itype_id fuel) const

Return total space to store specified fuel.

Definition at line 2025 of file character.cpp.

2026{
2027 int capacity = 0;
2028 for( const bionic_id &bid : get_bionics() ) {
2029 for( const itype_id &fl : bid->fuel_opts ) {
2030 if( get_value( bid.str() ).empty() || get_value( bid.str() ) == fl.str() ) {
2031 if( fl == fuel ) {
2032 capacity += bid->fuel_capacity;
2033 }
2034 }
2035 }
2036 }
2037 return capacity;
2038}

References get_bionics(), Creature::get_value(), and string_id< T >::str().

Referenced by draw_bionics_titlebar().

◆ get_type_of_scent()

scenttype_id Character::get_type_of_scent ( ) const

Definition at line 8715 of file character.cpp.

8716{
8717 return type_of_scent;
8718}
scenttype_id type_of_scent
Definition: character.h:2236

References type_of_scent.

Referenced by game::do_turn(), update_type_of_scent(), and change_scent_iuse::use().

◆ get_used_bionics_slots()

int Character::get_used_bionics_slots ( const bodypart_id bp) const

Definition at line 2481 of file bionics.cpp.

2482{
2483 int used_slots = 0;
2484 for( const bionic_id &bid : get_bionics() ) {
2485 auto search = bid->occupied_bodyparts.find( bp.id() );
2486 if( search != bid->occupied_bodyparts.end() ) {
2487 used_slots += search->second;
2488 }
2489 }
2490
2491 return used_slots;
2492}
static bool search(const ui_adaptor &om_ui, tripoint_abs_omt &curs, const tripoint_abs_omt &orig)

References get_bionics(), int_id< T >::id(), and overmap_ui::search().

Referenced by get_free_bionics_slots().

◆ get_visible_creatures()

std::vector< Creature * > Character::get_visible_creatures ( int  range) const

Returns all creatures that this player can see and that are in the given range.

This player object itself is never included. The player character (g->u) is checked and might be included (if applicable).

Parameters
rangeThe maximal distance (rl_dist), creatures at this distance or less are included.

Definition at line 10183 of file character.cpp.

10184{
10185 return g->get_creatures_if( [this, range]( const Creature & critter ) -> bool {
10186 return this != &critter && pos() != critter.pos() && // TODO: get rid of fake npcs (pos() check)
10187 rl_dist( pos(), critter.pos() ) <= range && sees( critter );
10188 } );
10189}

References g, Creature::pos(), pos(), rl_dist(), and sees().

Referenced by game::is_hostile_within(), game::list_items_monsters(), and game::mon_info_update().

◆ get_vision_modes()

const std::bitset< NUM_VISION_MODES > & Character::get_vision_modes ( ) const
inline

Definition at line 1516 of file character.h.

1516 {
1517 return vision_mode_cache;
1518 }

References vision_mode_cache.

◆ get_vision_threshold()

float Character::get_vision_threshold ( float  light_level) const

Returns the apparent light level at which the player can see.

This is adjusted by the light level at the character's position to simulate glare, etc, night vision only works if you are in the dark.

Definition at line 1716 of file character.cpp.

1717{
1719 // Debug vision always works with absurdly little light.
1720 return 0.01;
1721 }
1722
1723 // As light_level goes from LIGHT_AMBIENT_MINIMAL to LIGHT_AMBIENT_LIT,
1724 // dimming goes from 1.0 to 2.0.
1725 const float dimming_from_light = 1.0 + ( ( static_cast<float>( light_level ) -
1728
1729 // -1 because SOME math was changed from LIGHT_AMBIENT_MINIMAL to LIGHT_AMBIENT_LOW
1730 // but kept in other places.
1731 // *_LOW is the one actually used in math, *_MINIMAL is arbitrary.
1732 // TODO: Correct test cases and drop the ugliness
1733
1734 // This guarantees at least 1 tile of range
1735 static const float threshold_cap = vision::threshold_for_nv_range( 1 - 1 ) * LIGHT_AMBIENT_LOW /
1737
1738 return std::min( {static_cast<float>( LIGHT_AMBIENT_LOW ),
1739 vision::threshold_for_nv_range( nv_range - 1 ) * dimming_from_light,
1740 threshold_cap} );
1741}
@ DEBUG_NIGHTVISION
Definition: character.h:87
float nv_range
Definition: character.h:2150
static constexpr float LIGHT_AMBIENT_MINIMAL
Definition: lightmap.h:12
static constexpr float LIGHT_AMBIENT_LOW
Definition: lightmap.h:14
static constexpr float LIGHT_AMBIENT_LIT
Definition: lightmap.h:18
float threshold_for_nv_range(float range)
Returns the light level that darkness will have at this range from player.
Definition: character.cpp:1696

References DEBUG_NIGHTVISION, LIGHT_AMBIENT_LIT, LIGHT_AMBIENT_LOW, LIGHT_AMBIENT_MINIMAL, nv_range, vision::threshold_for_nv_range(), and vision_mode_cache.

Referenced by sight_range().

◆ get_weight()

units::mass Character::get_weight ( ) const
overridevirtual

Returns body weight plus weight of inventory and worn/wielded items.

Implements Creature.

Definition at line 3652 of file character.cpp.

3653{
3654 units::mass ret = 0_gram;
3655 units::mass wornWeight = std::accumulate( worn.begin(), worn.end(), 0_gram,
3656 []( units::mass sum, const item & itm ) {
3657 return sum + itm.weight();
3658 } );
3659
3660 ret += bodyweight(); // The base weight of the player's body
3661 ret += inv.weight(); // Weight of the stored inventory
3662 ret += wornWeight; // Weight of worn items
3663 ret += weapon.weight(); // Weight of wielded item
3664 ret += bionics_weight(); // Weight of installed bionics
3665 return ret;
3666}
units::mass bionics_weight() const
Definition: character.cpp:6723
units::mass bodyweight() const
Definition: character.cpp:6718
units::mass weight() const
Definition: inventory.cpp:997

References bionics_weight(), bodyweight(), inv, cata::hash64_detail::ret, weapon, inventory::weight(), item::weight(), and worn.

Referenced by vehicle::calc_mass_center(), can_mount(), npc::move_to(), monexamine::pet_menu(), swim_speed(), weigh_self_actor::use(), and game::walk_move().

◆ get_weight_string()

std::string Character::get_weight_string ( ) const

Definition at line 4524 of file character.cpp.

4525{
4526 double weight = convert_weight( bodyweight() );
4527 int display_weight = static_cast<int>( std::round( weight ) );
4528 return std::to_string( display_weight ) + " " + weight_units();
4529}
const char * weight_units()
Create a units label for a weight value.
double convert_weight(const units::mass &weight)
Convert weight in grams to units defined by user (kg or lbs)

References bodyweight(), convert_weight(), to_string(), and weight_units().

◆ get_working_arm_count()

int Character::get_working_arm_count ( ) const

Returns the number of functioning arms.

Definition at line 1208 of file character.cpp.

1209{
1211 return 0;
1212 }
1213
1214 int limb_count = 0;
1215 if( !is_limb_disabled( bodypart_id( "arm_l" ) ) ) {
1216 limb_count++;
1217 }
1218 if( !is_limb_disabled( bodypart_id( "arm_r" ) ) ) {
1219 limb_count++;
1220 }
1221
1222 return limb_count;
1223}
static const trait_id trait_SHELL2("SHELL2")

References has_active_mutation(), is_limb_disabled(), and trait_SHELL2.

Referenced by can_wield(), has_two_arms(), melee_attack(), avatar_action::plthrow(), and vehicle::start_engine().

◆ get_working_leg_count()

int Character::get_working_leg_count ( ) const

Returns the number of functioning legs.

Definition at line 1226 of file character.cpp.

1227{
1228 int limb_count = 0;
1229 if( !is_limb_broken( bodypart_id( "leg_l" ) ) ) {
1230 limb_count++;
1231 }
1232 if( !is_limb_broken( bodypart_id( "leg_r" ) ) ) {
1233 limb_count++;
1234 }
1235 return limb_count;
1236}

References is_limb_broken().

Referenced by best_shield(), character_martial_arts::can_leg_block(), can_run(), is_on_ground(), and avatar::set_movement_mode().

◆ getID()

character_id Character::getID ( ) const

Definition at line 483 of file character.cpp.

484{
485 return this->id;
486}

References id.

Referenced by add_addiction(), item::already_used_by_player(), talk_effect_t::apply(), apply_damage(), iuse::artifact(), mission::assign(), talk_function::assign_camp(), vehicle::assign_seat(), best_installer(), bionics_install_failure(), map::board_vehicle(), veh_interact::calc_overview(), debug_menu::character_edit_menu(), check_needs_extremes(), talk_function::clear_mission(), game::critter_by_id(), iuse::crowbar(), mattack::dermatik(), monster::die(), npc::die(), avatar::do_read(), npc::execute_action(), dig_activity_actor::finish(), hacking_activity_actor::finish(), npc::finish_read(), ranged::fire_gun(), talk_function::follow(), item::get_remaining_chapters(), hardcoded_effects(), heal(), talk_function::hostile(), hurtall(), npc::is_ally(), item_location::impl::item_on_person::item_on_person(), talk_function::leave(), avatar::load(), game::load(), npc::load_npc_template(), item::mark_as_used_by_player(), item::mark_chapter_as_read(), iuse::marloss(), marloss_common(), iuse::marloss_gel(), iuse::marloss_seed(), mend(), iuse::mininuke(), mount_creature(), mutagen_common_checks(), mutate_towards(), npc::mutiny(), iuse::mycus(), iuse::note_bionics(), kill_tracker::notify(), talk_function::npc_die(), mattack::nurse_operate(), mission::on_creature_death(), item::on_pickup(), perform_install(), perform_uninstall(), npc::randomize(), avatar::read(), npc::regen_ai_cache(), rem_addiction(), Creature::remove_effect(), game::reset_npc_dispositions(), map::rotate(), talk_effect_fun_t::set_add_mission(), vehicle_part::set_crew(), npc::set_fac(), npc::set_known_to_u(), npc::setpos(), game::start_game(), npc::start_read(), talk_function::start_training(), talk_function::stop_guard(), player::store(), survive_random_encounter(), npc::talk_to_u(), teleport::teleport(), test_crossing_threshold(), ranged::throw_item(), activity_handlers::train_finish(), npc::travel_overmap(), game::validate_npc_followers(), vomit(), and wake_up().

◆ gibType()

field_type_id Character::gibType ( ) const
overridevirtual

Implements Creature.

Definition at line 510 of file character.cpp.

511{
512 return fd_gibs_flesh;
513}
field_type_id fd_gibs_flesh
Definition: field_type.cpp:338

References fd_gibs_flesh.

◆ global_omt_location()

tripoint_abs_omt Character::global_omt_location ( ) const

Returns the location of the player in global overmap terrain coordinates.

Definition at line 6231 of file character.cpp.

6232{
6233 // TODO: fix point types
6235}
virtual tripoint global_square_location() const
Global position, expressed in map square coordinate system (the most detailed coordinate system),...
Definition: character.cpp:6221
point ms_to_omt_copy(const point &p)
coords::coord_point< tripoint, coords::origin::abs, coords::omt > tripoint_abs_omt
Definition: coordinates.h:493

References global_square_location(), and ms_to_omt_copy().

Referenced by talk_function::abandon_camp(), computer_session::action_map_sewer(), computer_session::action_map_subway(), computer_session::action_maps(), activate_bionic(), activate_mutation(), apply_persistent_morale(), iuse::artifact(), talk_function::assign_camp(), talk_function::basecamp_mission(), burn_fuel(), talk_function::caravan_dist(), ui::omap::choose_point(), talk_function::companion_choose_return(), talk_function::companion_list(), talk_function::companion_mission(), npc::consume_food_from_camp(), mission_start::create_hidden_lab_console(), mission_start::create_ice_lab_console(), mission_start::create_lab_console(), game::disp_NPCs(), item::display_name(), ui::omap::display_visible_weather(), ui::omap::display_weather(), game::do_turn(), overmap_ui::draw_ascii(), draw_env_compact(), draw_loc_labels(), draw_location_classic(), game::draw_minimap(), draw_minimap(), basecamp::faction_display(), npc::faction_display(), talk_function::field_build_1(), talk_function::field_build_2(), talk_function::field_harvest(), mission_start::find_safety(), overmapbuffer::fix_npcs(), get_basecamp(), get_mission_om_origin(), overmapbuffer::get_npcs_near_omt(), overmapbuffer::get_npcs_near_player(), overmap_ui::get_overmap_path_to(), npc::go_to_omt_destination(), talk_function::goto_location(), npc::guard_current_pos(), talk_function::individual_mission(), mission_start::kill_horde_master(), game::list_missions(), spell_effect::map_area(), trapfunc::map_regen(), npc::move(), overmap_los(), passive_power_gen(), game::perhaps_add_random_npc(), mission_start::place_deposit_box(), mission_start::place_npc_software(), process_turn(), npc::reach_omt_destination(), talk_function::recover_camp(), teleporter_callback::refresh(), npc::regen_ai_cache(), render_wind(), game::reset_npc_dispositions(), reveal_destination(), mission_start::reveal_lab_train_depot(), mission_util::reveal_om_ter(), conditional_t< T >::set_at_om_location(), npc::set_companion_mission(), npc::set_omt_destination(), talk_function::start_camp(), game::start_game(), activity_handlers::travel_do_turn(), npc::travel_overmap(), activity_handlers::tree_communion_do_turn(), update_bodytemp(), game::update_overmap_seen(), reveal_map_actor::use(), game::vertical_notes(), iuse::weather_tool(), npc::within_boundaries_of_camp(), and game::zones_manager().

◆ global_sm_location()

tripoint Character::global_sm_location ( ) const

◆ global_square_location()

tripoint Character::global_square_location ( ) const
virtual

Global position, expressed in map square coordinate system (the most detailed coordinate system), used by the map.

Reimplemented in npc.

Definition at line 6221 of file character.cpp.

6222{
6223 return get_map().getabs( position );
6224}
tripoint position
Definition: character.h:2095

References get_map(), map::getabs(), and position.

Referenced by global_omt_location(), and global_sm_location().

◆ handle_melee_wear()

bool Character::handle_melee_wear ( item shield,
float  wear_multiplier = 1.0f 
)

Calculates melee weapon wear-and-tear through use, returns true if item is destroyed.

Dexterity reduces chance of damaging your melee weapon Strength increases chance of damaging your melee weapon (NEGATIVE) Melee reduces chance of damaging your melee weapon

Definition at line 159 of file melee.cpp.

160{
161 if( wear_multiplier <= 0.0f ) {
162 return false;
163 }
164 // Here is where we handle wear and tear on things we use as melee weapons or shields.
165 if( shield.is_null() ) {
166 return false;
167 }
168
169 // UNBREAKABLE_MELEE items can't be damaged through melee combat usage.
170 if( shield.has_flag( "UNBREAKABLE_MELEE" ) ) {
171 return false;
172 }
173
174 /** @EFFECT_DEX reduces chance of damaging your melee weapon */
175
176 /** @EFFECT_STR increases chance of damaging your melee weapon (NEGATIVE) */
177
178 /** @EFFECT_MELEE reduces chance of damaging your melee weapon */
179 const float stat_factor = dex_cur / 2.0f
181 + ( 64.0f / std::max( str_cur, 4 ) );
182
183 float material_factor;
184
185 itype_id weak_comp;
186 itype_id big_comp = itype_id::NULL_ID();
187 // Fragile items that fall apart easily when used as a weapon due to poor construction quality
188 if( shield.has_flag( "FRAGILE_MELEE" ) ) {
189 const float fragile_factor = 6;
190 int weak_chip = INT_MAX;
191 units::volume big_vol = 0_ml;
192
193 // Items that should have no bearing on durability
194 const std::set<itype_id> blacklist = { itype_rag, itype_leather, itype_fur };
195
196 for( auto &comp : shield.components ) {
197 if( blacklist.count( comp.typeId() ) <= 0 ) {
198 if( weak_chip > comp.chip_resistance() ) {
199 weak_chip = comp.chip_resistance();
200 weak_comp = comp.typeId();
201 }
202 }
203 if( comp.volume() > big_vol ) {
204 big_vol = comp.volume();
205 big_comp = comp.typeId();
206 }
207 }
208 material_factor = ( weak_chip < INT_MAX ? weak_chip : shield.chip_resistance() ) / fragile_factor;
209 } else {
210 material_factor = shield.chip_resistance();
211 }
212 int damage_chance = static_cast<int>( stat_factor * material_factor / wear_multiplier );
213 // DURABLE_MELEE items are made to hit stuff and they do it well, so they're considered to be a lot tougher
214 // than other weapons made of the same materials.
215 if( shield.has_flag( "DURABLE_MELEE" ) ) {
216 damage_chance *= 4;
217 }
218
219 if( damage_chance > 0 && !one_in( damage_chance ) ) {
220 return false;
221 }
222
223 auto str = shield.tname(); // save name before we apply damage
224
225 if( !shield.inc_damage() ) {
226 add_msg_player_or_npc( m_bad, _( "Your %s is damaged by the force of the blow!" ),
227 _( "<npcname>'s %s is damaged by the force of the blow!" ),
228 str );
229 return false;
230 }
231
232 // Dump its contents on the ground
233 // Destroy irremovable mods, if any
234
235 for( auto mod : shield.gunmods() ) {
236 if( mod->is_irremovable() ) {
237 remove_item( *mod );
238 }
239 }
240
241 // Preserve item temporarily for component breakdown
242 item temp = shield;
243
244 shield.contents.spill_contents( pos() );
245
246 remove_item( shield );
247
248 // Breakdown fragile weapons into components
249 if( temp.has_flag( "FRAGILE_MELEE" ) && !temp.components.empty() ) {
250 add_msg_player_or_npc( m_bad, _( "Your %s breaks apart!" ),
251 _( "<npcname>'s %s breaks apart!" ),
252 str );
253
254 for( auto &comp : temp.components ) {
255 int break_chance = comp.typeId() == weak_comp ? 2 : 8;
256
257 if( one_in( break_chance ) ) {
258 add_msg_if_player( m_bad, _( "The %s is destroyed!" ), comp.tname() );
259 continue;
260 }
261
262 if( comp.typeId() == big_comp && !is_armed() ) {
263 wield( comp );
264 } else {
265 g->m.add_item_or_charges( pos(), comp );
266 }
267 }
268 } else {
269 add_msg_player_or_npc( m_bad, _( "Your %s is destroyed by the blow!" ),
270 _( "<npcname>'s %s is destroyed by the blow!" ),
271 str );
272 }
273
274 return true;
275}
virtual bool wield(item &target)=0
Removes currently wielded item (if any) and replaces it with the target item.
bool spill_contents(const tripoint &pos)
int chip_resistance(bool worst=false) const
Returns resistance to being damaged by attack against the item itself.
Definition: item.cpp:6197
bool inc_damage(damage_type dt)
Increment item damage by itype::damage_scale constrained by max_damage.
Definition: item.cpp:6258
std::vector< item * > gunmods()
Returns all gunmods currently attached to this item (always empty if item not a gun)
Definition: item.cpp:7740
static const itype_id itype_rag("rag")
static const itype_id itype_fur("fur")
static const itype_id itype_leather("leather")

References _, Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), item::chip_resistance(), item::components, item::contents, dex_cur, g, get_skill_level(), item::gunmods(), item::has_flag(), item::inc_damage(), is_armed(), item::is_null(), itype_fur, itype_leather, itype_rag, m_bad, string_id< itype >::NULL_ID(), one_in(), pos(), visitable< Character >::remove_item(), skill_melee, item_contents::spill_contents(), str_cur, item::tname(), and wield().

Referenced by block_hit(), melee_special_effects(), reach_attack(), and smash().

◆ hardcoded_effects()

void Character::hardcoded_effects ( effect it)

Handles the still hard-coded effects.

Maximum Strength increases number of insects hatched from dermatik infection Intelligence decreases occurrence of itching from formication effect

Definition at line 472 of file player_hardcoded_effects.cpp.

473{
474 if( auto buff = ma_buff::from_effect( it ) ) {
475 if( buff->is_valid_character( *this ) ) {
476 buff->apply_character( *this );
477 } else {
478 it.set_duration( 0_turns ); // removes the effect
479 }
480 return;
481 }
482 using hc_effect_fun = std::function<void( player &, effect & )>;
483 static const std::map<efftype_id, hc_effect_fun> hc_effect_map = {{
496 }
497 };
498 const efftype_id &id = it.get_id();
499 const auto &iter = hc_effect_map.find( id );
500 if( iter != hc_effect_map.end() ) {
501 iter->second( *as_player(), it );
502 return;
503 }
504
505 const time_duration dur = it.get_duration();
506 int intense = it.get_intensity();
507 body_part bp = it.get_bp()->token;
508 bool sleeping = has_effect( effect_sleep );
509 if( id == effect_dermatik ) {
510 bool triggered = false;
511 int formication_chance = 3600;
512 if( dur < 4_hours ) {
513 formication_chance += 14400 - to_turns<int>( dur );
514 }
515 if( one_in( formication_chance ) ) {
516 add_effect( effect_formication, 60_minutes, bp );
517 }
518 if( dur < 1_days && one_in( 14400 ) ) {
519 vomit();
520 }
521 if( dur > 1_days ) {
522 // Spawn some larvae!
523 // Choose how many insects; more for large characters
524 ///\EFFECT_STR_MAX increases number of insects hatched from dermatik infection
525 int num_insects = rng( 1, std::min( 3, str_max / 3 ) );
526 apply_damage( nullptr, convert_bp( bp ).id(), rng( 2, 4 ) * num_insects );
527 // Figure out where they may be placed
529 _( "Your flesh crawls; insects tear through the flesh and begin to emerge!" ),
530 _( "Insects begin to emerge from <npcname>'s skin!" ) );
531 for( ; num_insects > 0; num_insects-- ) {
532 if( monster *const grub = g->place_critter_around( mon_dermatik_larva, pos(), 1 ) ) {
533 if( one_in( 3 ) ) {
534 grub->friendly = -1;
535 }
536 }
537 }
538 g->events().send<event_type::dermatik_eggs_hatch>( getID() );
540 moves -= 600;
541 triggered = true;
542 }
543 if( triggered ) {
544 // Set ourselves up for removal
545 it.set_duration( 0_turns );
546 } else {
547 // Count duration up
548 it.mod_duration( 1_turns );
549 }
550 } else if( id == effect_formication ) {
551 ///\EFFECT_INT decreases occurrence of itching from formication effect
552 if( x_in_y( intense, 600 + 300 * get_int() ) && !has_effect( effect_narcosis ) ) {
553 if( !is_npc() ) {
554 //~ %s is bodypart in accusative.
555 add_msg( m_warning, _( "You start scratching your %s!" ), body_part_name_accusative( bp ) );
556 g->u.cancel_activity();
557 } else if( g->u.sees( pos() ) ) {
558 //~ 1$s is NPC name, 2$s is bodypart in accusative.
559 add_msg( _( "%1$s starts scratching their %2$s!" ), name, body_part_name_accusative( bp ) );
560 }
561 moves -= 150;
562 apply_damage( nullptr, convert_bp( bp ).id(), 1 );
563 }
564 } else if( id == effect_evil ) {
565 // Worn or wielded; diminished effects
566 bool lesserEvil = weapon.has_effect_when_wielded( AEP_EVIL ) ||
568 for( auto &w : worn ) {
569 if( w.has_effect_when_worn( AEP_EVIL ) ) {
570 lesserEvil = true;
571 break;
572 }
573 }
574 if( lesserEvil ) {
575 // Only minor effects, some even good!
576 mod_str_bonus( dur > 450_minutes ? 10.0 : dur / 45_minutes );
577 if( dur < 1_hours ) {
578 mod_dex_bonus( 1 );
579 } else {
580 int dex_mod = -( dur > 360_minutes ? 10.0 : ( dur - 1_hours ) / 30_minutes );
581 mod_dex_bonus( dex_mod );
582 add_miss_reason( _( "Why waste your time on that insignificant speck?" ), -dex_mod );
583 }
584 mod_int_bonus( -( dur > 300_minutes ? 10.0 : ( dur - 50_minutes ) / 25_minutes ) );
585 mod_per_bonus( -( dur > 480_minutes ? 10.0 : ( dur - 80_minutes ) / 40_minutes ) );
586 } else {
587 // Major effects, all bad.
588 mod_str_bonus( -( dur > 500_minutes ? 10.0 : dur / 50_minutes ) );
589 int dex_mod = -( dur > 600_minutes ? 10.0 : dur / 60_minutes );
590 mod_dex_bonus( dex_mod );
591 add_miss_reason( _( "Why waste your time on that insignificant speck?" ), -dex_mod );
592 mod_int_bonus( -( dur > 450_minutes ? 10.0 : dur / 45_minutes ) );
593 mod_per_bonus( -( dur > 400_minutes ? 10.0 : dur / 40_minutes ) );
594 }
595 } else if( id == effect_attention ) {
596 if( intense > 6 ) {
597 if( one_in( 7200 - ( intense * 450 ) ) ) {
599 _( "You feel something reaching out to you, before reality around you frays!" ) );
600 if( has_psy_protection( *this, 10 ) ) {
601 // Transfers half of remaining duration of nether attention, tinfoil only sometimes helps
602 add_effect( effect_teleglow, ( dur / 2 ), num_bp, ( intense / 2 ) );
603 } else {
604 // Transfers all remaining duration of nether attention to dimensional instability
605 add_effect( effect_teleglow, dur, num_bp, intense );
606 }
607 it.set_duration( 0_turns );
608 }
609 if( one_in( 8000 - ( intense * 500 ) ) && one_in( 2 ) ) {
610 if( !is_npc() ) {
611 add_msg( m_bad, _( "You pass out from the strain of something bearing down on your mind." ) );
612 }
613 fall_asleep( 2_hours );
614 if( one_in( 10 ) ) {
615 it.set_duration( 0_turns );
616 }
617 it.mod_duration( -20_minutes * intense );
618 it.mod_intensity( -1 );
619 }
620 }
621 if( intense > 4 ) {
622 if( one_in( 6000 - ( intense * 375 ) ) ) {
623 if( has_psy_protection( *this, 4 ) ) {
624 add_msg_if_player( m_bad, _( "You feel something probing your mind, but it is rebuffed!" ) );
625 } else {
626 add_msg_if_player( m_bad, _( "A terrifying image in the back out your mind paralyzes you." ) );
628 moves -= 4 * get_speed();
629 }
630 it.mod_duration( -10_minutes * intense );
631 if( one_in( 2 ) ) {
632 it.mod_intensity( -1 );
633 }
634 }
635 if( one_turn_in( 1200_minutes - ( intense * 90_minutes ) ) ) {
636 if( has_psy_protection( *this, 4 ) ) {
637 add_msg_if_player( m_bad, _( "You feel a buzzing in the back of your mind, but it passes." ) );
638 } else {
639 add_msg_if_player( m_bad, _( "You feel something scream in the back of your mind!" ) );
640 add_effect( effect_dazed, rng( 1_minutes, 2_minutes ) );
641 }
642 it.mod_duration( -10_minutes * intense );
643 if( one_in( 3 ) ) {
644 it.mod_intensity( -1 );
645 }
646 }
647 }
648 if( intense > 2 ) {
649 if( one_turn_in( 1200_minutes - ( intense * 90_minutes ) ) ) {
650 add_msg_if_player( m_bad, _( "Your vision is filled with bright lights…" ) );
651 add_effect( effect_blind, rng( 1_minutes, 2_minutes ) );
652 it.mod_duration( -10_minutes * intense );
653 if( one_in( 4 ) ) {
654 it.mod_intensity( -1 );
655 }
656 }
657 if( one_in( 5000 ) && !has_effect( effect_nausea ) ) {
658 add_msg_if_player( m_bad, _( "A wave of nausea passes over you." ) );
659 add_effect( effect_nausea, 5_minutes );
660 }
661 }
662 if( one_in( 5000 ) && !has_effect( effect_hallu ) ) {
663 add_msg_if_player( m_bad, _( "Shifting shapes dance on the edge of your vision." ) );
664 add_effect( effect_hallu, 4_hours );
665 it.mod_duration( -10_minutes * intense );
666 }
667 if( one_turn_in( 40_minutes ) ) {
668 if( has_psy_protection( *this, 4 ) ) {
669 add_msg_if_player( m_bad, _( "You feel weird for a moment, but it passes." ) );
670 } else {
671 // Less morale drop and faster decay than Psychosis negative messages, but more frequent
672 const translation snip = SNIPPET.random_from_category( "nether_attention_watching" ).value_or(
673 translation() );
674 add_msg_if_player( m_warning, "%s", snip );
675 add_morale( MORALE_FEELING_BAD, -10, -50, 60_minutes, 20_minutes, true );
676 }
677 }
678 } else if( id == effect_teleglow ) {
679 // Each teleportation increases intensity by 1, 2 intensities per tier of effect.
680 // TODO: Include a chance to teleport to the nether realm.
681 // TODO: This with regards to NPCS
682 if( !is_player() ) {
683 // NO, no teleporting around the player because an NPC has teleglow!
684 return;
685 }
686 if( intense > 6 ) {
687 if( one_in( 6000 - ( intense * 250 ) ) ) {
688 if( !is_npc() ) {
689 add_msg( _( "Glowing lights surround you, and you teleport." ) );
690 }
691 teleport::teleport( *this );
692 g->events().send<event_type::teleglow_teleports>( getID() );
693 if( one_in( 10 ) ) {
694 // Set ourselves up for removal
695 it.set_duration( 0_turns );
696 }
697 // Since teleporting grants 1 intensity and 30 minutes duration,
698 // if it doesn't remove it'll get more intense but shorter.
699 it.mod_duration( -20_minutes * intense );
700 }
701 if( one_in( 7200 - ( intense * 250 ) ) ) {
702 add_msg_if_player( m_bad, _( "You are beset with a vision of a prowling beast." ) );
703 for( const tripoint &dest : g->m.points_in_radius( pos(), 6 ) ) {
704 if( g->m.is_cornerfloor( dest ) ) {
705 g->m.add_field( dest, fd_tindalos_rift, 3 );
706 add_msg_if_player( m_info, _( "Your surroundings are permeated with a foul scent." ) );
707 break;
708 }
709 }
710 if( one_in( 2 ) ) {
711 // Set ourselves up for removal
712 it.set_duration( 0_turns );
713 }
714 it.mod_intensity( -1 );
715 }
716 }
717 if( intense > 4 ) {
718 // Once every 4 hours baseline, once every 2 hours max
719 if( one_turn_in( 14_hours - ( intense * 90_minutes ) ) ) {
720 tripoint dest( 0, 0, posz() );
721 int &x = dest.x;
722 int &y = dest.y;
723 int tries = 0;
724 do {
725 x = posx() + rng( -4, 4 );
726 y = posy() + rng( -4, 4 );
727 tries++;
728 if( tries >= 10 ) {
729 break;
730 }
731 } while( g->critter_at( dest ) );
732 if( tries < 10 ) {
733 if( g->m.impassable( dest ) ) {
734 g->m.make_rubble( dest, f_rubble_rock, true );
735 }
737 GROUP_NETHER );
738 g->place_critter_at( spawn_details.name, dest );
739 if( g->u.sees( dest ) ) {
740 g->cancel_activity_or_ignore_query( distraction_type::hostile_spotted_far,
741 _( "A monster appears nearby!" ) );
742 add_msg( m_warning, _( "A portal opens nearby, and a monster crawls through!" ) );
743 }
744 it.mod_duration( -10_minutes * intense );
745 it.mod_intensity( -1 );
746 }
747 }
748 if( one_in( 21000 - ( intense * 1125 ) ) ) {
749 add_msg_if_player( m_bad, _( "You shudder suddenly." ) );
750 mutate();
751 it.mod_duration( -10_minutes * intense );
752 if( one_in( 2 ) ) {
753 it.mod_intensity( -1 );
754 }
755 }
756 }
757 if( intense > 2 ) {
758 if( one_in( 10000 ) ) {
759 if( !has_trait( trait_M_IMMUNE ) ) {
760 add_effect( effect_fungus, 1_turns, num_bp );
761 add_msg_if_player( m_bad, _( "You smell mold, and your skin itches." ) );
762 } else {
763 add_msg_if_player( m_info, _( "We have many colonists awaiting passage." ) );
764 }
765 // Set ourselves up for removal
766 it.set_duration( 0_turns );
767 }
768 if( one_in( 5000 ) ) {
769 // Like with the glow anomaly trap, but lower max and bypasses radsuits
770 add_msg_if_player( m_bad, _( "A blue flash of radiation permeates your vision briefly!" ) );
771 irradiate( rng( 10, 20 ), true );
772 it.mod_duration( -10_minutes * intense );
773 if( one_in( 4 ) ) {
774 it.mod_intensity( -1 );
775 }
776 }
777 }
778 if( one_in( 4000 ) ) {
779 add_msg_if_player( m_bad, _( "You're suddenly covered in ectoplasm." ) );
780 add_effect( effect_boomered, 10_minutes );
781 it.mod_duration( -10_minutes * intense );
782 }
783 if( one_in( 5000 ) ) {
784 add_msg_if_player( m_bad, _( "A strange sound reverberates around the edges of reality." ) );
785 // Comparable to the humming anomaly trap, with a narrower range
786 int volume = rng( 25, 150 );
787 std::string sfx;
788 if( volume <= 50 ) {
789 sfx = _( "hrmmm" );
790 } else if( volume <= 100 ) {
791 sfx = _( "HRMMM" );
792 } else {
793 sfx = _( "VRMMMMMM" );
794 }
795 sounds::sound( pos(), volume, sounds::sound_t::activity, sfx, false, "humming", "machinery" );
796 }
797 } else if( id == effect_asthma ) {
799 add_msg_if_player( m_good, _( "Your asthma attack stops." ) );
800 it.set_duration( 0_turns );
801 } else if( dur > 2_hours ) {
802 add_msg_if_player( m_bad, _( "Your asthma overcomes you.\nYou asphyxiate." ) );
803 g->events().send<event_type::dies_from_asthma_attack>( getID() );
804 hurtall( 500, nullptr );
805 } else if( dur > 70_minutes ) {
806 if( one_in( 120 ) ) {
807 add_msg_if_player( m_bad, _( "You wheeze and gasp for air." ) );
808 }
809 }
810 } else if( id == effect_brainworms ) {
811 if( one_in( 1536 ) ) {
812 add_msg_if_player( m_bad, _( "Your head aches faintly." ) );
813 }
814 if( one_in( 6144 ) ) {
815 mod_healthy_mod( -10, -100 );
816 apply_damage( nullptr, bodypart_id( "head" ), rng( 0, 1 ) );
817 if( !has_effect( effect_visuals ) ) {
818 add_msg_if_player( m_bad, _( "Your vision is getting fuzzy." ) );
819 add_effect( effect_visuals, rng( 1_minutes, 60_minutes ) );
820 }
821 }
822 if( one_in( 24576 ) ) {
823 mod_healthy_mod( -10, -100 );
824 apply_damage( nullptr, bodypart_id( "head" ), rng( 1, 2 ) );
825 if( !is_blind() && !sleeping ) {
826 add_msg_if_player( m_bad, _( "Your vision goes black!" ) );
827 add_effect( effect_blind, rng( 5_turns, 20_turns ) );
828 }
829 }
830 } else if( id == effect_tapeworm ) {
831 if( one_in( 3072 ) ) {
832 add_msg_if_player( m_bad, _( "Your bowels ache." ) );
833 }
834 } else if( id == effect_bloodworms ) {
835 if( one_in( 3072 ) ) {
836 add_msg_if_player( m_bad, _( "Your veins itch." ) );
837 }
838 } else if( id == effect_paincysts ) {
839 if( one_in( 3072 ) ) {
840 add_msg_if_player( m_bad, _( "Your muscles feel like they're knotted and tired." ) );
841 }
842 } else if( id == effect_datura ) {
843 if( dur > 100_minutes && focus_pool >= 1 && one_in( 24 ) ) {
844 focus_pool--;
845 }
846 if( dur > 200_minutes && one_in( 48 ) && get_stim() < 20 ) {
847 mod_stim( 1 );
848 }
849 if( dur > 300_minutes && focus_pool >= 1 && one_in( 12 ) ) {
850 focus_pool--;
851 }
852 if( dur > 400_minutes && one_in( 384 ) ) {
853 mod_pain( rng( -1, -8 ) );
854 }
855 if( ( !has_effect( effect_hallu ) ) && ( dur > 500_minutes && one_in( 24 ) ) ) {
856 add_effect( effect_hallu, 6_hours );
857 }
858 if( dur > 600_minutes && one_in( 768 ) ) {
859 mod_pain( rng( -3, -24 ) );
860 if( dur > 800_minutes && one_in( 16 ) ) {
862 _( "You're experiencing loss of basic motor skills and blurred vision. Your mind recoils in horror, unable to communicate with your spinal column." ) );
863 add_msg_if_player( m_bad, _( "You stagger and fall!" ) );
864 add_effect( effect_downed, rng( 1_turns, 4_turns ), num_bp, 0, true );
865 if( one_in( 8 ) || x_in_y( character_effects::vomit_mod( *this ), 10 ) ) {
866 vomit();
867 }
868 }
869 }
870 if( dur > 700_minutes && focus_pool >= 1 ) {
871 focus_pool--;
872 }
873 if( dur > 800_minutes && one_in( 1536 ) ) {
874 add_effect( effect_visuals, rng( 4_minutes, 20_minutes ) );
875 mod_pain( rng( -8, -40 ) );
876 }
877 if( dur > 1200_minutes && one_in( 1536 ) ) {
878 add_msg_if_player( m_bad, _( "There's some kind of big machine in the sky." ) );
879 add_effect( effect_visuals, rng( 8_minutes, 40_minutes ) );
880 if( one_in( 32 ) ) {
881 add_msg_if_player( m_bad, _( "It's some kind of electric snake, coming right at you!" ) );
882 mod_pain( rng( 4, 40 ) );
883 vomit();
884 }
885 }
886 if( dur > 1400_minutes && one_in( 768 ) ) {
888 _( "Order us some golf shoes, otherwise we'll never get out of this place alive." ) );
889 add_effect( effect_visuals, rng( 40_minutes, 200_minutes ) );
890 if( one_in( 8 ) ) {
892 _( "The possibility of physical and mental collapse is now very real." ) );
893 if( one_in( 2 ) || x_in_y( character_effects::vomit_mod( *this ), 10 ) ) {
894 add_msg_if_player( m_bad, _( "No one should be asked to handle this trip." ) );
895 vomit();
896 mod_pain( rng( 8, 40 ) );
897 }
898 }
899 }
900
901 if( dur > 1800_minutes && one_in( 300 * 512 ) ) {
902 if( !has_trait( trait_NOPAIN ) ) {
904 _( "Your heart spasms painfully and stops, dragging you back to reality as you die." ) );
905 } else {
907 _( "You dissolve into beautiful paroxysms of energy. Life fades from your nebulae and you are no more." ) );
908 }
909 g->events().send<event_type::dies_from_drug_overdose>( getID(), id );
910 set_part_hp_cur( bodypart_id( "torso" ), 0 );
911 }
912 } else if( id == effect_grabbed ) {
914 int zed_number = 0;
915 for( auto &dest : g->m.points_in_radius( pos(), 1, 0 ) ) {
916 const monster *const mon = g->critter_at<monster>( dest );
917 if( mon && mon->has_effect( effect_grabbing ) ) {
918 zed_number += mon->get_grab_strength();
919 }
920 }
921 if( zed_number > 0 ) {
922 //If intensity isn't pass the cap, average it with # of zeds
923 add_effect( effect_grabbed, 2_turns, bp_torso, ( intense + zed_number ) / 2 );
924 }
925 } else if( id == effect_bite ) {
926 bool recovered = false;
927 /* Recovery chances, use binomial distributions if balancing here. Healing in the bite
928 * stage provides additional benefits, so both the bite stage chance of healing and
929 * the cumulative chances for spontaneous healing are both given.
930 * Cumulative heal chances for the bite + infection stages:
931 * -200 health - 38.6%
932 * 0 health - 46.8%
933 * 200 health - 53.7%
934 *
935 * Heal chances in the bite stage:
936 * -200 health - 23.4%
937 * 0 health - 28.3%
938 * 200 health - 32.9%
939 *
940 * Cumulative heal chances the bite + infection stages with the resistant mutation:
941 * -200 health - 82.6%
942 * 0 health - 84.5%
943 * 200 health - 86.1%
944 *
945 * Heal chances in the bite stage with the resistant mutation:
946 * -200 health - 60.7%
947 * 0 health - 63.2%
948 * 200 health - 65.6%
949 */
950 if( dur % 10_turns == 0_turns ) {
951 int recover_factor = 100;
952 if( has_effect( effect_recover ) ) {
953 recover_factor -= get_effect_dur( effect_recover ) / 1_hours;
954 }
955 if( has_trait( trait_INFRESIST ) ) {
956 recover_factor += 200;
957 }
958 if( has_effect( effect_panacea ) ) {
959 recover_factor = 648000; //panacea is a guaranteed cure
960 } else if( has_effect( effect_strong_antibiotic ) ) {
961 recover_factor += 400;
962 } else if( has_effect( effect_antibiotic ) ) {
963 recover_factor += 200;
964 } else if( has_effect( effect_weak_antibiotic ) ) {
965 recover_factor += 100;
966 }
967 recover_factor += get_healthy() / 10;
968
969 if( x_in_y( recover_factor, 648000 ) ) {
970 //~ %s is bodypart name.
971 add_msg_if_player( m_good, _( "Your %s wound begins to feel better!" ),
972 body_part_name( bp ) );
973 // Set ourselves up for removal
974 it.set_duration( 0_turns );
975 recovered = true;
976 }
977 }
978 if( !recovered ) {
979 // Move up to infection
980 // Infection resistance can keep us in bite phase arbitrarily long
981 if( dur > 6_hours && !has_trait( trait_INFRESIST ) ) {
982 add_effect( effect_infected, 1_turns, bp );
983 // Set ourselves up for removal
984 it.set_duration( 0_turns );
985 } else if( has_effect( effect_strong_antibiotic ) ) {
986 // Strong antibiotic reverses progress
987 it.mod_duration( -1_turns );
988 } else if( has_effect( effect_antibiotic ) ) {
989 // Normal antibiotic prevents progression
990 } else if( has_effect( effect_weak_antibiotic ) ) {
991 if( calendar::once_every( 4_turns ) ) {
992 // Weak antibiotic slows down to a quarter
993 it.mod_duration( 1_turns );
994 }
995 } else {
996 it.mod_duration( 1_turns );
997 }
998 }
999 } else if( id == effect_infected ) {
1000 bool recovered = false;
1001 // Recovery chance, use binomial distributions if balancing here.
1002 // See "bite" for balancing notes on this.
1003 if( dur % 10_turns == 0_turns ) {
1004 int recover_factor = 100;
1005 if( has_effect( effect_recover ) ) {
1006 recover_factor -= get_effect_dur( effect_recover ) / 1_hours;
1007 }
1008 if( has_trait( trait_INFRESIST ) ) {
1009 recover_factor += 200;
1010 }
1011 if( has_effect( effect_panacea ) ) {
1012 recover_factor = 5184000;
1013 } else if( has_effect( effect_strong_antibiotic ) ) {
1014 recover_factor += 400;
1015 } else if( has_effect( effect_antibiotic ) ) {
1016 recover_factor += 200;
1017 } else if( has_effect( effect_weak_antibiotic ) ) {
1018 recover_factor += 100;
1019 }
1020 recover_factor += get_healthy() / 10;
1021
1022 if( x_in_y( recover_factor, 5184000 ) ) {
1023 //~ %s is bodypart name.
1024 add_msg_if_player( m_good, _( "Your %s wound begins to feel better!" ),
1025 body_part_name( bp ) );
1026 add_effect( effect_recover, 4 * dur );
1027 // Set ourselves up for removal
1028 it.set_duration( 0_turns );
1029 recovered = true;
1030 }
1031 }
1032 if( !recovered ) {
1033 // Don't kill if the player is on antibiotics
1035 it.mod_duration( -1_turns );
1036 } else if( has_effect( effect_antibiotic ) ) {
1037 // No progression
1038 } else if( has_effect( effect_weak_antibiotic ) ) {
1039 if( calendar::once_every( 4_turns ) ) {
1040 it.mod_duration( 1_turns );
1041 }
1042 } else if( dur > 1_days ) {
1043 add_msg_if_player( m_bad, _( "You succumb to the infection." ) );
1044 g->events().send<event_type::dies_of_infection>( getID() );
1045 hurtall( 500, nullptr );
1046 } else {
1047 it.mod_duration( 1_turns );
1048 }
1049 }
1050 } else if( id == effect_lying_down ) {
1051 set_moves( 0 );
1052 if( character_funcs::roll_can_sleep( *this ) ) {
1053 fall_asleep();
1054 // Set ourselves up for removal
1055 it.set_duration( 0_turns );
1056 }
1057 if( dur == 1_turns && !sleeping ) {
1058 add_msg_if_player( _( "You try to sleep, but can't…" ) );
1059 }
1060 } else if( id == effect_sleep ) {
1061 set_moves( 0 );
1062 if( is_avatar() ) {
1064 }
1065
1066 if( has_effect( effect_narcosis ) && get_fatigue() <= 25 ) {
1067 set_fatigue( 25 ); //Prevent us from waking up naturally while under anesthesia
1068 }
1069
1070 if( get_fatigue() <= 10 && !has_effect( effect_narcosis ) ) {
1071 set_fatigue( 0 );
1073 add_msg_if_player( m_good, _( "You feel well rested." ) );
1074 } else {
1076 _( "You feel physically rested, but you haven't been able to catch up on your missed sleep yet." ) );
1077 }
1078 it.set_duration( 0_seconds );
1079 }
1080
1081 // TODO: Move this to update_needs when NPCs can mutate
1082 if( calendar::once_every( 10_minutes ) && ( has_trait( trait_CHLOROMORPH ) ||
1084 g->m.is_outside( pos() ) ) {
1085 if( has_trait( trait_CHLOROMORPH ) ) {
1086 // Hunger and thirst fall before your Chloromorphic physiology!
1087 if( g->natural_light_level( posz() ) >= 12 &&
1088 get_weather().weather_id->sun_intensity >= sun_intensity_type::light ) {
1089 if( get_stored_kcal() < max_stored_kcal() - 50 ) {
1090 mod_stored_kcal( 50 );
1091 }
1093 mod_thirst( -5 );
1094 }
1095 }
1096 }
1097 if( has_trait( trait_M_SKIN3 ) ) {
1098 // Spores happen!
1099 if( g->m.has_flag_ter_or_furn( "FUNGUS", pos() ) ) {
1100 if( get_fatigue() >= 0 ) {
1101 mod_fatigue( -5 ); // Local guides need less sleep on fungal soil
1102 }
1103 if( calendar::once_every( 1_hours ) ) {
1104 spores(); // spawn some P O O F Y B O I S
1105 }
1106 }
1107 }
1108 if( has_trait( trait_WATERSLEEP ) ) {
1109 mod_fatigue( -3 ); // Fish sleep less in water
1110 }
1111 }
1112
1113 // Check mutation category strengths to see if we're mutated enough to get a dream
1114 std::string highcat = get_highest_category();
1115 int highest = mutation_category_level[highcat];
1116
1117 // Determine the strength of effects or dreams based upon category strength
1118 int strength = 0; // Category too weak for any effect or dream
1119 if( crossed_threshold() ) {
1120 strength = 4; // Post-human.
1121 } else if( highest >= 20 && highest < 35 ) {
1122 strength = 1; // Low strength
1123 } else if( highest >= 35 && highest < 50 ) {
1124 strength = 2; // Medium strength
1125 } else if( highest >= 50 ) {
1126 strength = 3; // High strength
1127 }
1128
1129 // Get a dream if category strength is high enough.
1130 if( strength != 0 ) {
1131 //Once every 6 / 3 / 2 hours, with a bit of randomness
1132 if( calendar::once_every( 6_hours / strength ) && one_in( 3 ) ) {
1133 // Select a dream
1134 std::string dream = dreams::get_random_for_category( highcat, strength );
1135 if( !dream.empty() ) {
1137 }
1138 // Mycus folks upgrade in their sleep.
1139 if( has_trait( trait_THRESH_MYCUS ) ) {
1140 if( one_in( 8 ) ) {
1141 mutate_category( "MYCUS" );
1142 mod_stored_nutr( 10 );
1143 mod_thirst( 10 );
1144 mod_fatigue( 5 );
1145 }
1146 }
1147 }
1148 }
1149
1150 bool woke_up = false;
1151 int tirednessVal = rng( 5, 200 ) + rng( 0, std::abs( get_fatigue() * 2 * 5 ) );
1152 if( !is_blind() && !has_effect( effect_narcosis ) ) {
1153 if( !has_trait(
1154 trait_SEESLEEP ) ) { // People who can see while sleeping are acclimated to the light.
1156 // So you can too sleep through noon
1157 if( ( tirednessVal * 1.25 ) < g->m.ambient_light_at( pos() ) && ( get_fatigue() < 10 ||
1158 one_in( get_fatigue() / 2 ) ) ) {
1159 add_msg_if_player( _( "It's too bright to sleep." ) );
1160 // Set ourselves up for removal
1161 it.set_duration( 0_turns );
1162 woke_up = true;
1163 }
1164 // Ursine hibernators would likely do so indoors. Plants, though, might be in the sun.
1165 } else if( has_trait( trait_HIBERNATE ) ) {
1166 if( ( tirednessVal * 5 ) < g->m.ambient_light_at( pos() ) && ( get_fatigue() < 10 ||
1167 one_in( get_fatigue() / 2 ) ) ) {
1168 add_msg_if_player( _( "It's too bright to sleep." ) );
1169 // Set ourselves up for removal
1170 it.set_duration( 0_turns );
1171 woke_up = true;
1172 }
1173 } else if( tirednessVal < g->m.ambient_light_at( pos() ) && ( get_fatigue() < 10 ||
1174 one_in( get_fatigue() / 2 ) ) ) {
1175 add_msg_if_player( _( "It's too bright to sleep." ) );
1176 // Set ourselves up for removal
1177 it.set_duration( 0_turns );
1178 woke_up = true;
1179 }
1180 } else if( has_active_mutation( trait_SEESLEEP ) ) {
1181 Creature *hostile_critter = g->is_hostile_very_close();
1182 if( hostile_critter != nullptr ) {
1183 add_msg_if_player( _( "You see %s approaching!" ),
1184 hostile_critter->disp_name() );
1185 it.set_duration( 0_turns );
1186 woke_up = true;
1187 }
1188 }
1189 }
1190
1191 // Have we already woken up?
1192 if( !woke_up && !has_effect( effect_narcosis ) ) {
1193 // Cold or heat may wake you up.
1194 // Player will sleep through cold or heat if fatigued enough
1195 for( const body_part bp : all_body_parts ) {
1196 if( temp_cur[bp] < BODYTEMP_VERY_COLD - get_fatigue() / 2 ) {
1197 if( one_in( 30000 ) ) {
1198 add_msg_if_player( _( "You toss and turn trying to keep warm." ) );
1199 }
1200 if( temp_cur[bp] < BODYTEMP_FREEZING - get_fatigue() / 2 ||
1201 one_in( temp_cur[bp] * 6 + 30000 ) ) {
1202 add_msg_if_player( m_bad, _( "It's too cold to sleep." ) );
1203 // Set ourselves up for removal
1204 it.set_duration( 0_turns );
1205 woke_up = true;
1206 break;
1207 }
1208 } else if( temp_cur[bp] > BODYTEMP_VERY_HOT + get_fatigue() / 2 ) {
1209 if( one_in( 30000 ) ) {
1210 add_msg_if_player( _( "You toss and turn in the heat." ) );
1211 }
1212 if( temp_cur[bp] > BODYTEMP_SCORCHING + get_fatigue() / 2 ||
1213 one_in( 90000 - temp_cur[bp] ) ) {
1214 add_msg_if_player( m_bad, _( "It's too hot to sleep." ) );
1215 // Set ourselves up for removal
1216 it.set_duration( 0_turns );
1217 woke_up = true;
1218 break;
1219 }
1220 }
1221 }
1223 one_in( 43200 ) && is_player() ) ) {
1224 if( one_in( 2 ) ) {
1225 sound_hallu();
1226 } else {
1227 int max_count = rng( 1, 3 );
1228 int count = 0;
1229 for( const tripoint &mp : g->m.points_in_radius( pos(), 1 ) ) {
1230 if( mp == pos() ) {
1231 continue;
1232 }
1233 if( g->m.has_flag( "FLAT", mp ) &&
1234 g->m.pl_sees( mp, 2 ) ) {
1235 g->spawn_hallucination( mp );
1236 if( ++count > max_count ) {
1237 break;
1238 }
1239 }
1240 }
1241 }
1242 it.set_duration( 0_turns );
1243 woke_up = true;
1244 }
1245 }
1246
1247 // A bit of a hack: check if we are about to wake up for any reason, including regular
1248 // timing out of sleep
1249 if( dur == 1_turns || woke_up ) {
1250 wake_up();
1251 }
1252 } else if( id == effect_alarm_clock ) {
1253 if( in_sleep_state() ) {
1254 const bool asleep = has_effect( effect_sleep );
1255 if( has_bionic( bio_watch ) ) {
1256 if( dur == 1_turns ) {
1257 if( !asleep ) {
1258 add_msg_if_player( _( "Your internal chronometer went off and you haven't slept a wink." ) );
1260 } else {
1261 // Secure the flag before wake_up() clears the effect
1262 bool slept_through = has_effect( effect_slept_through_alarm );
1263 wake_up();
1264 if( slept_through ) {
1265 add_msg_if_player( _( "Your internal chronometer finally wakes you up." ) );
1266 } else {
1267 add_msg_if_player( _( "Your internal chronometer wakes you up." ) );
1268 }
1269 }
1270 }
1271 } else {
1272 if( asleep && dur == 1_turns ) {
1275 }
1276 // 10 minute automatic snooze
1277 it.mod_duration( 10_minutes );
1278 } else if( dur == 2_turns ) {
1279 // let the sound code handle the wake-up part
1280 sounds::sound( pos(), 16, sounds::sound_t::alarm, _( "beep-beep-beep!" ), false, "tool",
1281 "alarm_clock" );
1282 }
1283 }
1284 } else {
1285 if( dur == 1_turns ) {
1286 if( is_avatar() && has_alarm_clock() ) {
1287 sounds::sound( pos(), 16, sounds::sound_t::alarm, _( "beep-beep-beep!" ), false, "tool",
1288 "alarm_clock" );
1289 const std::string alarm = _( "Your alarm is going off." );
1290 g->cancel_activity_or_ignore_query( distraction_type::alert, alarm );
1291 add_msg( _( "Your alarm went off." ) );
1292 }
1293 }
1294 }
1295 } else if( id == effect_mending ) {
1296 if( !is_limb_broken( convert_bp( bp ) ) ) {
1297 it.set_duration( 0_turns );
1298 }
1299 } else if( id == effect_disabled ) {
1300 if( !is_limb_broken( convert_bp( bp ) ) ) {
1302 }
1303 } else if( id == effect_panacea ) {
1304 // restore health all body parts, dramatically reduce pain
1305 healall( 1 );
1306 mod_pain( -10 );
1307 }
1308}
bool has_psy_protection(const Character &c, int partial_chance)
Returns true if the player has a psyshield artifact, or sometimes if wearing tinfoil.
void mutate_category(const std::string &mut_cat)
Picks a random valid mutation in a category and mutate_towards() it.
Definition: mutation.cpp:1034
void sound_hallu()
Creates an auditory hallucination.
Definition: suffer.cpp:1710
void wake_up()
Removes "sleep" and "lying_down".
Definition: character.cpp:7533
int posz() const override
Definition: character.h:792
virtual void mod_per_bonus(int nper)
Definition: character.cpp:4172
virtual void mod_dex_bonus(int ndex)
Definition: character.cpp:4167
void mutate()
Picks a random valid mutation and gives it to the Character, possibly removing/changing others along ...
Definition: mutation.cpp:835
bool crossed_threshold() const
Returns true if the player has crossed a mutation threshold Player can only cross one mutation thresh...
Definition: character.cpp:8672
bool is_blind() const
Returns true if the player isn't able to see.
Definition: character.cpp:6237
bool has_alarm_clock() const
Returns true if the player or their vehicle has an alarm clock.
Definition: character.cpp:708
virtual void mod_str_bonus(int nstr)
Definition: character.cpp:4162
std::string get_highest_category() const
Returns the highest mutation category.
Definition: character.cpp:7797
virtual void mod_stored_nutr(int nnutr)
Definition: character.cpp:4292
void hurtall(int dam, Creature *source, bool disturb=true)
Hurts all body parts for dam, no armor reduction.
Definition: character.cpp:8617
int get_speed() const override
Definition: character.cpp:4112
bool irradiate(float rads, bool bypass=false)
Handles mitigation and application of radiation.
Definition: suffer.cpp:1536
virtual void mod_int_bonus(int nint)
Definition: character.cpp:4177
virtual int get_num_blocks_bonus() const
Definition: creature.cpp:1454
virtual void set_num_blocks_bonus(int nblocks)
Definition: creature.cpp:1720
void set_moves(int nmoves)
Definition: creature.cpp:1418
static MonsterGroupResult GetResultFromGroup(const mongroup_id &group, int *quantity=nullptr)
Definition: mongroup.cpp:98
void set_duration(const time_duration &dur, bool alert=false)
Sets the duration, capping at max_duration if it exists.
Definition: effect.cpp:805
int mod_intensity(int mod, bool alert=false)
Modify intensity of effect capped by range [1..max_intensity].
Definition: effect.cpp:886
void pump_events()
Resize & refresh if necessary, process all pending window events, and ignore keypresses.
bool has_effect_when_carried(art_effect_passive effect) const
Does the item provide the artifact effect when it is carried?
Definition: item.cpp:9757
bool has_effect_when_wielded(art_effect_passive effect) const
Does the item provide the artifact effect when it is wielded?
Definition: item.cpp:9739
static const ma_buff * from_effect(const effect &eff)
int get_grab_strength() const
Definition: monster.cpp:2015
Definition: player.h:84
@ AEP_EVIL
Definition: enums.h:127
@ AEP_SCHIZO
Definition: enums.h:128
@ dies_from_asthma_attack
@ dermatik_eggs_hatch
@ teleglow_teleports
field_type_id fd_tindalos_rift
Definition: field_type.cpp:387
input_manager inp_mngr
Definition: input.cpp:109
furn_id f_rubble_rock
Definition: mapdata.cpp:1099
const morale_type MORALE_FEELING_BAD("morale_feeling_bad")
double vomit_mod(const Character &ch)
Returns the modifier value used for vomiting effects.
bool roll_can_sleep(Character &who)
Checked each turn during "lying_down", returns true if the avatar falls asleep.
constexpr size_t count()
Definition: fmtlib_core.h:1073
std::string get_random_for_category(const std::string &cat, int strength)
Returns a random dream description that matches given category and strength.
Definition: sounds.h:92
static const trait_id trait_M_SKIN3("M_SKIN3")
static const efftype_id effect_bloodworms("bloodworms")
static const efftype_id effect_downed("downed")
static const efftype_id effect_fungus("fungus")
static const efftype_id effect_blind("blind")
static const efftype_id effect_datura("datura")
static const efftype_id effect_teleglow("teleglow")
static const efftype_id effect_dermatik("dermatik")
static const efftype_id effect_bleed("bleed")
static const efftype_id effect_narcosis("narcosis")
static const efftype_id effect_adrenaline("adrenaline")
static const efftype_id effect_infected("infected")
static const efftype_id effect_cold("cold")
static const efftype_id effect_attention("attention")
static const efftype_id effect_recover("recover")
static const efftype_id effect_asthma("asthma")
static const efftype_id effect_antibiotic("antibiotic")
static const trait_id trait_M_IMMUNE("M_IMMUNE")
static void eff_fun_bloated(player &u, effect &it)
static const efftype_id effect_hallu("hallu")
static void eff_fun_cold(player &u, effect &it)
static const efftype_id effect_bite("bite")
static const mtype_id mon_dermatik_larva("mon_dermatik_larva")
static const trait_id trait_THRESH_MYCUS("THRESH_MYCUS")
static const efftype_id effect_tapeworm("tapeworm")
static const efftype_id effect_boomered("boomered")
static const trait_id trait_HIBERNATE("HIBERNATE")
static const trait_id trait_SEESLEEP("SEESLEEP")
static const efftype_id effect_hot("hot")
static const mongroup_id GROUP_NETHER("GROUP_NETHER")
static void eff_fun_hot(player &u, effect &it)
static void eff_fun_bleed(player &u, effect &it)
static const efftype_id effect_spores("spores")
static const efftype_id effect_evil("evil")
static const trait_id trait_INFRESIST("INFRESIST")
static const efftype_id effect_grabbing("grabbing")
static const efftype_id effect_weak_antibiotic("weak_antibiotic")
static void eff_fun_fungus(player &u, effect &it)
static const efftype_id effect_panacea("panacea")
static const efftype_id effect_visuals("visuals")
static const efftype_id effect_dazed("dazed")
static void eff_fun_toxin_buildup(player &u, effect &it)
static void eff_fun_spores(player &u, effect &it)
static const bionic_id bio_watch("bio_watch")
static const efftype_id effect_paincysts("paincysts")
static const efftype_id effect_toxin_buildup("toxin_buildup")
static const efftype_id effect_sleep("sleep")
static const efftype_id effect_bloated("bloated")
static void eff_fun_mutating(player &u, effect &it)
static const efftype_id effect_fearparalyze("fearparalyze")
static const efftype_id effect_strong_antibiotic("strong_antibiotic")
static const trait_id trait_CHLOROMORPH("CHLOROMORPH")
static const trait_id trait_WATERSLEEP("WATERSLEEP")
static const efftype_id effect_nausea("nausea")
static const efftype_id effect_rat("rat")
static void eff_fun_frostbite(player &u, effect &it)
static void eff_fun_onfire(player &u, effect &it)
static const efftype_id effect_lying_down("lying_down")
static const efftype_id effect_slept_through_alarm("slept_through_alarm")
static void eff_fun_rat(player &u, effect &it)
static const efftype_id effect_mutating("mutating")
static void eff_fun_hallu(player &u, effect &it)
static const efftype_id effect_formication("formication")
static const trait_id trait_HEAVYSLEEPER2("HEAVYSLEEPER2")
static const efftype_id effect_mending("mending")
static const efftype_id effect_grabbed("grabbed")
static const efftype_id effect_disabled("disabled")
static const efftype_id effect_alarm_clock("alarm_clock")
static const trait_id trait_NOPAIN("NOPAIN")
static const trait_id trait_SCHIZOPHRENIC("SCHIZOPHRENIC")
static const efftype_id effect_brainworms("brainworms")
static const efftype_id effect_onfire("onfire")
static const efftype_id effect_frostbite("frostbite")
bool one_turn_in(const time_duration &duration)
Definition: rng.cpp:70
mtype_id name
Definition: mongroup.h:53

References _, activity, sounds::activity, Creature::add_effect(), add_miss_reason(), add_morale(), add_msg(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), AEP_EVIL, AEP_SCHIZO, sounds::alarm, alert, all_body_parts, apply_damage(), Creature::as_player(), bio_watch, body_part_name(), body_part_name_accusative(), BODYTEMP_FREEZING, BODYTEMP_SCORCHING, BODYTEMP_VERY_COLD, BODYTEMP_VERY_HOT, bp_torso, convert_bp(), detail::count(), crossed_threshold(), dermatik_eggs_hatch, dies_from_asthma_attack, dies_from_drug_overdose, dies_of_infection, Creature::disp_name(), eff_fun_bleed(), eff_fun_bloated(), eff_fun_cold(), eff_fun_frostbite(), eff_fun_fungus(), eff_fun_hallu(), eff_fun_hot(), eff_fun_mutating(), eff_fun_onfire(), eff_fun_rat(), eff_fun_spores(), eff_fun_toxin_buildup(), effect_adrenaline, effect_alarm_clock, effect_antibiotic, effect_asthma, effect_attention, effect_bite, effect_bleed, effect_blind, effect_bloated, effect_bloodworms, effect_boomered, effect_brainworms, effect_cold, effect_datura, effect_dazed, effect_dermatik, effect_disabled, effect_downed, effect_evil, effect_fearparalyze, effect_formication, effect_frostbite, effect_fungus, effect_grabbed, effect_grabbing, effect_hallu, effect_hot, effect_infected, effect_lying_down, effect_mending, effect_mutating, effect_narcosis, effect_nausea, effect_onfire, effect_paincysts, effect_panacea, effect_rat, effect_recover, effect_sleep, effect_slept_through_alarm, effect_spores, effect_strong_antibiotic, effect_tapeworm, effect_teleglow, effect_toxin_buildup, effect_visuals, effect_weak_antibiotic, f_rubble_rock, fall_asleep(), fd_tindalos_rift, focus_pool, ma_buff::from_effect(), g, effect::get_bp(), effect::get_duration(), Creature::get_effect_dur(), get_fatigue(), monster::get_grab_strength(), get_healthy(), get_highest_category(), effect::get_id(), get_int(), effect::get_intensity(), Creature::get_num_blocks_bonus(), dreams::get_random_for_category(), get_sleep_deprivation(), get_speed(), get_stim(), get_stored_kcal(), get_thirst(), get_weather(), getID(), MonsterGroupManager::GetResultFromGroup(), GROUP_NETHER, harmless, has_active_mutation(), has_alarm_clock(), has_artifact_with(), has_bionic(), Creature::has_effect(), item::has_effect_when_carried(), item::has_effect_when_wielded(), has_psy_protection(), has_trait(), healall(), hostile_spotted_far, hurtall(), id, in_sleep_state(), inp_mngr, irradiate(), Creature::is_avatar(), is_blind(), is_limb_broken(), Creature::is_npc(), Creature::is_player(), light, m_bad, m_good, m_info, m_warning, max_stored_kcal(), mod_dex_bonus(), effect::mod_duration(), mod_fatigue(), mod_healthy_mod(), mod_int_bonus(), effect::mod_intensity(), mod_pain(), mod_per_bonus(), mod_stim(), mod_stored_kcal(), mod_stored_nutr(), mod_str_bonus(), mod_thirst(), mon_dermatik_larva, MORALE_FEELING_BAD, Creature::moves, mutate(), mutate_category(), mutation_category_level, name, MonsterGroupResult::name, num_bp, calendar::once_every(), one_in(), one_turn_in(), pos(), posx(), posy(), posz(), input_manager::pump_events(), snippet_library::random_from_category(), Creature::remove_effect(), rng(), character_funcs::roll_can_sleep(), effect::set_duration(), set_fatigue(), Creature::set_moves(), Creature::set_num_blocks_bonus(), Creature::set_part_hp_cur(), player_activity::set_to_null(), SNIPPET, sounds::sound(), sound_hallu(), spores(), str_max, teleglow_teleports, teleport::teleport(), temp_cur, body_part_type::token, trait_CHLOROMORPH, trait_HEAVYSLEEPER2, trait_HIBERNATE, trait_INFRESIST, trait_M_IMMUNE, trait_M_SKIN3, trait_NOPAIN, trait_SCHIZOPHRENIC, trait_SEESLEEP, trait_THRESH_MYCUS, trait_WATERSLEEP, turgid, vomit(), character_effects::vomit_mod(), wake_up(), weapon, worn, tripoint::x, x_in_y(), and tripoint::y.

Referenced by process_one_effect().

◆ has_active_bionic()

bool Character::has_active_bionic ( const bionic_id b) const

Returns true if the player has the entered bionic id and it is powered on.

Definition at line 1805 of file character.cpp.

1806{
1807 for( const bionic &i : *my_bionics ) {
1808 if( i.id == b ) {
1809 return ( i.powered && i.incapacitated_time == 0_turns );
1810 }
1811 }
1812 return false;
1813}

References b, and my_bionics.

Referenced by absorb_hit(), activate_bionic(), active_light(), adjust_for_focus(), attack_cost(), basic_symbol_color(), burn_move_stamina(), character_martial_arts::can_arm_block(), can_feed_furnace_with(), can_feed_reactor_with(), character_martial_arts::can_leg_block(), comestible_inventory_preset::comestible_inventory_preset(), crit_chance(), avatar::do_read(), do_skill_rust(), game::do_turn(), draw_bionics_titlebar(), draw_skills_tab(), iuse::ehandcuffs(), npc::finish_read(), get_env_resist(), get_hit_weapon(), ranged::gunmode_checks_weapon(), game::handle_action(), has_fire(), has_nv(), hearing_ability(), impact(), in_climate_control(), is_blind(), is_deaf(), is_immune_damage(), is_immune_field(), ma_requirements::is_valid_character(), game::item_action_menu(), trapfunc::ledge(), melee_attack(), melee_special_effects(), modify_morale(), game::monmove(), mut_cbm_encumb(), on_hit(), game::on_move_effects(), perform_technique(), character_martial_arts::pick_style(), trapfunc::pit(), trapfunc::pit_glass(), trapfunc::pit_spikes(), map::player_in_field(), process_items(), character_funcs::rate_sleep_spot(), recalc_sight_limits(), npc::recharge_cbm(), game::remoteveh(), reset_stats(), mattack::riotbot(), roll_bash_damage(), character_funcs::roll_can_sleep(), roll_cut_damage(), roll_stab_damage(), run_cost(), character_funcs::search_surroundings(), sees_with_specials(), game::setremoteveh(), iuse::solarpack(), suffer_from_radiation(), ranged::throw_item(), throw_range(), avatar_funcs::try_to_sleep(), character_funcs::try_uncanny_dodge(), update_health(), update_needs(), update_stamina(), use_charges(), use_fire(), and npc::wants_to_recharge_cbm().

◆ has_active_item()

bool Character::has_active_item ( const itype_id id) const

Whether the player carries an active item of the given item type.

Definition at line 2479 of file character.cpp.

2480{
2481 return has_item_with( [id]( const item & it ) {
2482 return it.active && it.typeId() == id;
2483 } );
2484}

References item::active, visitable< Character >::has_item_with(), and item::typeId().

Referenced by deactivate_bionic(), game::handle_action(), iuse::mp3(), game::remoteveh(), and game::setremoteveh().

◆ has_active_mutation()

◆ has_activity() [1/2]

bool Character::has_activity ( const activity_id type) const

◆ has_activity() [2/2]

bool Character::has_activity ( const std::vector< activity_id > &  types) const

Check if player currently has any of the given activities.

Definition at line 9183 of file character.cpp.

9184{
9185 return std::find( types.begin(), types.end(), activity.id() ) != types.end();
9186}
FMT_CONSTEXPR bool find(Ptr first, Ptr last, T value, Ptr &out)

References activity, detail::find(), and player_activity::id().

◆ has_addiction()

bool Character::has_addiction ( add_type  type) const

Returns true if the player has an addiction of the specified type.

Definition at line 1942 of file suffer.cpp.

1943{
1944 return std::any_of( addictions.begin(), addictions.end(),
1945 [type]( const addiction & ad ) {
1946 return ad.type == type && ad.intensity >= MIN_ADDICTION_LEVEL;
1947 } );
1948}

References addictions, and type.

Referenced by character_funcs::rate_sleep_spot().

◆ has_alarm_clock()

bool Character::has_alarm_clock ( ) const

Returns true if the player or their vehicle has an alarm clock.

Definition at line 708 of file character.cpp.

709{
710 map &here = get_map();
711 return ( has_item_with_flag( "ALARMCLOCK", true ) ||
712 ( here.veh_at( pos() ) &&
713 !empty( here.veh_at( pos() )->vehicle().get_avail_parts( "ALARMCLOCK" ) ) ) ||
715}
static const bionic_id bio_watch("bio_watch")
bool has_item_with_flag(const std::string &flag, bool need_charges=false) const
Definition: character.cpp:9537

References bio_watch, get_map(), has_bionic(), has_item_with_flag(), pos(), map::veh_at(), and vehicle.

Referenced by hardcoded_effects(), sleep(), and wait().

◆ has_any_bionic()

bool Character::has_any_bionic ( ) const

Returns true if the player has any bionic.

Definition at line 1815 of file character.cpp.

1816{
1817 return !get_bionics().empty();
1818}

References get_bionics().

Referenced by mattack::nurse_operate().

◆ has_artifact_with()

bool Character::has_artifact_with ( art_effect_passive  effect) const
virtual

Reimplemented in npc.

Definition at line 3181 of file character.cpp.

3182{
3184 return true;
3185 }
3186 for( auto &i : worn ) {
3187 if( i.has_effect_when_worn( effect ) ) {
3188 return true;
3189 }
3190 }
3191 return has_item_with( [effect]( const item & it ) {
3192 return it.has_effect_when_carried( effect );
3193 } );
3194}

References item::has_effect_when_carried(), item::has_effect_when_wielded(), visitable< Character >::has_item_with(), weapon, and worn.

Referenced by active_light(), basic_symbol_color(), deal_damage(), item::food_info(), hardcoded_effects(), is_immune_damage(), is_invisible(), melee_attack(), map::open_door(), recalc_sight_limits(), recalc_speed_bonus(), suffer_from_artifacts(), suffer_while_awake(), update_health(), game::walk_move(), and weight_capacity().

◆ has_base_trait()

bool Character::has_base_trait ( const trait_id b) const

Returns true if the player has the entered starting trait.

Definition at line 121 of file mutation.cpp.

122{
123 // Look only at base traits
124 return my_traits.find( b ) != my_traits.end();
125}

References b, and my_traits.

Referenced by build_mut_dependency_map(), do_purify(), wish_mutate_callback::key(), mutate_towards(), old_mutate(), iuse::purify_iv(), iuse::purify_smart(), remove_mutation(), detail::show_mutations_ui_internal(), and debug_menu::wishmutate().

◆ has_bionic()

bool Character::has_bionic ( const bionic_id b) const

Returns true if the player has the entered bionic id.

Definition at line 1795 of file character.cpp.

1796{
1797 for( const bionic_id &bid : get_bionics() ) {
1798 if( bid == b ) {
1799 return true;
1800 }
1801 }
1802 return false;
1803}

References b, and get_bionics().

Referenced by npc::activate_bionic_by_id(), add_bionic(), iexamine::autodoc(), autodoc_internal(), bionics_install_failure(), talk_trial::calc_chance(), calc_needs_rates(), character_martial_arts::can_arm_block(), character_martial_arts::can_leg_block(), npc::can_read(), can_uninstall_bionic(), install_bionic_actor::can_use(), item::color_in_inventory(), consume_effects(), consume_med(), activity_handlers::cracking_do_turn(), deactivate_bionic(), npc::deactivate_bionic_by_id(), draw_env_compact(), draw_speed_tab(), draw_time_classic(), eat(), iuse::einktabletpc(), iexamine::fireplace(), item::food_info(), avatar::get_book_reader(), bionic_install_preset::get_denial(), bionic_install_surgeon_preset::get_denial(), get_temp(), ranged::get_weapon_dispersion(), hardcoded_effects(), has_alarm_clock(), has_enough_anesth(), has_fire(), has_watch(), is_immune_effect(), player::load(), game::on_move_effects(), activity_handlers::operation_do_turn(), overmap_sight_range(), iexamine::pay_gas(), sounds::process_sound_markers(), read_speed(), recalc_sight_limits(), recalc_speed_bonus(), iuse::robotcontrol(), roll_cut_damage(), roll_stab_damage(), run_cost(), iexamine::safe(), conditional_t< T >::set_has_bionics(), sight_impaired(), suffer_from_asthma(), suffer_from_bad_bionics(), suffer_from_radiation(), suffer_from_sunburn(), suffer_while_underwater(), try_start_hacking(), update_bodytemp(), consume_drug_iuse::use(), npc::use_bionic_by_id(), game::use_computer(), use_fire(), volume_capacity_reduced_by(), avatar::wake_up(), game::walk_move(), and will_eat().

◆ has_bionics()

bool Character::has_bionics ( ) const

Whether character has any bionics installed.

Definition at line 2610 of file bionics.cpp.

2611{
2612 return !my_bionics->empty() || has_max_power();
2613}

References has_max_power(), and my_bionics.

Referenced by conditional_t< T >::set_has_bionics().

◆ has_charges()

bool Character::has_charges ( const itype_id it,
int  quantity,
const std::function< bool(const item &)> &  filter = return_true<item> 
) const

Definition at line 9554 of file character.cpp.

9556{
9557 if( it == itype_fire || it == itype_apparatus ) {
9558 return has_fire( quantity );
9559 }
9560 if( it == itype_UPS && is_mounted() &&
9561 mounted_creature.get()->has_flag( MF_RIDEABLE_MECH ) ) {
9562 auto mons = mounted_creature.get();
9563 return quantity <= mons->battery_item->ammo_remaining();
9564 }
9565 if( it == itype_bio_armor ) {
9566 int mod_qty = 0;
9567 float efficiency = 1;
9568 for( const bionic &bio : *my_bionics ) {
9569 if( bio.powered && bio.info().has_flag( flag_BIONIC_ARMOR_INTERFACE ) ) {
9570 efficiency = std::max( efficiency, bio.info().fuel_efficiency );
9571 }
9572 }
9573 if( efficiency == 1 ) {
9574 debugmsg( "Player lacks a bionic armor interface with fuel efficiency field." );
9575 }
9576 mod_qty = quantity / efficiency;
9577 return ( has_power() && get_power_level() >= units::from_kilojoule( mod_qty ) );
9578 }
9579 return charges_of( it, quantity, filter ) == quantity;
9580}
static const itype_id itype_fire("fire")
static const flag_str_id flag_BIONIC_ARMOR_INTERFACE("BIONIC_ARMOR_INTERFACE")
static const itype_id itype_apparatus("apparatus")
bool has_power() const
Definition: character.cpp:1927
bool has_fire(int quantity) const
Definition: character.cpp:9701

References visitable< Character >::charges_of(), debugmsg, flag_BIONIC_ARMOR_INTERFACE, units::from_kilojoule(), get_power_level(), has_fire(), has_power(), is_mounted(), itype_apparatus, itype_bio_armor, itype_fire, itype_UPS, MF_RIDEABLE_MECH, mounted_creature, and my_bionics.

Referenced by iexamine::arcfurnace_empty(), iuse::cable_attach(), can_eat(), iexamine::can_fertilize(), can_reload(), cauterize_actor::can_use(), craft_command::check_item_components_missing(), craft_command::check_tool_components_missing(), consume_charges(), consume_med(), consume_remote_fuel(), player::craft_consume_tools(), iuse::ecig(), activity_handlers::fertilize_plot_do_turn(), find_remote_fuel(), crafting::find_tool_component(), iuse::firecracker_pack(), avatar_funcs::gunmod_add(), ranged::gunmode_checks_weapon(), has_enough_charges(), has_fire(), npc::heal_self(), iexamine::kiln_empty(), npc::move(), iexamine::pay_gas(), avatar_action::reload(), talk_effect_fun_t::set_consume_item(), conditional_t< T >::set_has_items(), talk_effect_fun_t::set_u_sell_item(), smoker_activate(), iuse::smoking(), suffer_from_asthma(), try_consume(), try_start_hacking(), consume_drug_iuse::use(), use_charges_if_avail(), and use_fire().

◆ has_child_flag()

bool Character::has_child_flag ( const trait_id flag) const

Returns true if the player has the entered mutation child flag.

Definition at line 1475 of file mutation.cpp.

1476{
1477 for( const trait_id &elem : flag->replacements ) {
1478 const trait_id &tmp = elem;
1479 if( has_trait( tmp ) || has_child_flag( tmp ) ) {
1480 return true;
1481 }
1482 }
1483 return false;
1484}
bool has_child_flag(const trait_id &flag) const
Returns true if the player has the entered mutation child flag.
Definition: mutation.cpp:1475

References has_child_flag(), has_trait(), and mutation_branch::replacements.

Referenced by has_child_flag(), mutate_towards(), mutation_ok(), and remove_child_flag().

◆ has_destination()

◆ has_destination_activity()

bool Character::has_destination_activity ( ) const

◆ has_distant_destination()

bool Character::has_distant_destination ( ) const

Definition at line 10455 of file character.cpp.

10456{
10459}
static const activity_id ACT_TRAVELLING("ACT_TRAVELLING")
std::vector< tripoint_abs_omt > omt_path
Route for overmap scale traveling.
Definition: character.h:1803

References ACT_TRAVELLING, get_destination_activity(), has_destination(), player_activity::id(), player_activity::is_null(), and omt_path.

Referenced by game::cancel_activity_or_ignore_query(), game::cancel_activity_query(), and game::do_turn().

◆ has_enough_anesth()

bool Character::has_enough_anesth ( const itype cbm,
player patient 
)

Has enough anesthetic for surgery.

Definition at line 1820 of file bionics.cpp.

1821{
1822 if( !cbm->bionic ) {
1823 debugmsg( "has_enough_anesth( const itype *cbm ): %s is not a bionic", cbm->get_id() );
1824 return false;
1825 }
1826
1829 return true;
1830 }
1831
1832 const int weight = 7;
1833 const requirement_data req_anesth = *requirement_id( "anesthetic" ) *
1834 cbm->bionic->difficulty * 2 * weight;
1835
1837}
static const bionic_id bio_painkiller("bio_painkiller")
static const trait_id trait_DEBUG_BIONICS("DEBUG_BIONICS")
static const trait_id trait_NOPAIN("NOPAIN")
bool is_crafting_component(const item &component)
Default filter for crafting component searches.
Definition: item.h:2262
cata::value_ptr< islot_bionic > bionic
Definition: itype.h:863
bool can_make_with_inventory(const inventory &crafting_inv, const std::function< bool(const item &)> &filter, int batch=1, cost_adjustment=cost_adjustment::none) const
Returns true if the requirements are fufilled by the filtered inventory.
string_id< requirement_data > requirement_id
Definition: type_id.h:143

References bio_painkiller, itype::bionic, requirement_data::can_make_with_inventory(), crafting_inventory(), debugmsg, itype::get_id(), has_bionic(), has_trait(), is_crafting_component(), trait_DEBUG_BIONICS, and trait_NOPAIN.

Referenced by bionic_install_preset::get_denial(), and bionic_uninstall_preset::get_denial().

◆ has_enough_charges()

bool Character::has_enough_charges ( const item it,
bool  show_msg 
) const

Has the item enough charges to invoke its use function? Also checks if UPS from this player is used instead of item charges.

Definition at line 7320 of file character.cpp.

7321{
7322 if( !it.is_tool() || !it.ammo_required() ) {
7323 return true;
7324 }
7325 if( it.is_power_armor() ) {
7326 if( ( character_funcs::can_interface_armor( *this ) &&
7329 it.ammo_sufficient() ) {
7330 return true;
7331 }
7332
7333 if( show_msg ) {
7334 if( it.has_flag( flag_USE_UPS ) ) {
7336 vgettext( "Your %s needs %d charge, from some UPS or a Bionic Power Interface.",
7337 "Your %s needs %d charges, from some UPS or a Bionic Power Interface.",
7338 it.ammo_required() ),
7339 it.tname(), it.ammo_required() );
7340 } else {
7342 vgettext( "Your %s needs %d charge, from a Bionic Power Interface.",
7343 "Your %s needs %d charges, from a Bionic Power Interface.",
7344 it.ammo_required() ),
7345 it.tname(), it.ammo_required() );
7346 }
7347 }
7348 return false;
7349 }
7350 if( it.has_flag( flag_USE_UPS ) ) {
7351 if( has_charges( itype_UPS, it.ammo_required() ) || it.ammo_sufficient() ) {
7352 return true;
7353 }
7354 if( show_msg ) {
7356 vgettext( "Your %s needs %d charge from some UPS.",
7357 "Your %s needs %d charges from some UPS.",
7358 it.ammo_required() ),
7359 it.tname(), it.ammo_required() );
7360 }
7361 return false;
7362 } else if( !it.ammo_sufficient() ) {
7363 if( show_msg ) {
7365 vgettext( "Your %s has %d charge but needs %d.",
7366 "Your %s has %d charges but needs %d.",
7367 it.ammo_remaining() ),
7368 it.tname(), it.ammo_remaining(), it.ammo_required() );
7369 }
7370 return false;
7371 }
7372 return true;
7373}
bool ammo_sufficient(int qty=1) const
Check if sufficient ammo is loaded for given number of uses.
Definition: item.cpp:7480

References Creature::add_msg_if_player(), item::ammo_remaining(), item::ammo_required(), item::ammo_sufficient(), character_funcs::can_interface_armor(), flag_USE_UPS(), has_charges(), item::has_flag(), item::is_power_armor(), item::is_tool(), itype_bio_armor, itype_UPS, m_info, item::tname(), and vgettext().

Referenced by activatable_inventory_preset::get_denial(), invoke_item(), iuse::jackhammer(), and iuse::note_bionics().

◆ has_fire()

bool Character::has_fire ( int  quantity) const

Definition at line 9701 of file character.cpp.

9702{
9703 // TODO: Replace this with a "tool produces fire" flag.
9704
9705 if( get_map().has_nearby_fire( pos() ) ) {
9706 return true;
9707 } else if( has_item_with_flag( "FIRE" ) ) {
9708 return true;
9709 } else if( has_item_with_flag( "FIRESTARTER" ) ) {
9710 auto firestarters = all_items_with_flag( "FIRESTARTER" );
9711 for( auto &i : firestarters ) {
9712 if( !i->type->can_have_charges() ) {
9713 const use_function *usef = i->type->get_use( "firestarter" );
9714 if( !usef ) {
9715 debugmsg( "failed to get use func 'firestarter' for item '%s'", i->typeId().c_str() );
9716 continue;
9717 }
9718 const firestarter_actor *actor = dynamic_cast<const firestarter_actor *>( usef->get_actor_ptr() );
9719 if( actor->can_use( *this->as_character(), *i, false, tripoint_zero ).success() ) {
9720 return true;
9721 }
9722 } else if( has_charges( i->typeId(), quantity ) ) {
9723 return true;
9724 }
9725 }
9726 } else if( has_active_bionic( bio_tools ) && get_power_level() > quantity * 5_kJ ) {
9727 return true;
9728 } else if( has_bionic( bio_lighter ) && get_power_level() > quantity * 5_kJ ) {
9729 return true;
9730 } else if( has_bionic( bio_laser ) && get_power_level() > quantity * 5_kJ ) {
9731 return true;
9732 } else if( is_npc() ) {
9733 // HACK: A hack to make NPCs use their Molotovs
9734 return true;
9735 }
9736 return false;
9737}
static const bionic_id bio_lighter("bio_lighter")
static const bionic_id bio_laser("bio_laser")
static const bionic_id bio_tools("bio_tools")
std::vector< const item * > all_items_with_flag(const std::string &flag) const
All items that have the given flag (item::has_flag).
Definition: character.cpp:9547
Starts a fire instantly.
Definition: iuse_actor.h:529
ret_val< bool > can_use(const Character &, const item &, bool, const tripoint &) const override
iuse_actor * get_actor_ptr()
Definition: iuse.h:314

References all_items_with_flag(), bio_laser, bio_lighter, bio_tools, firestarter_actor::can_use(), debugmsg, use_function::get_actor_ptr(), get_map(), get_power_level(), has_active_bionic(), has_bionic(), has_charges(), has_item_with_flag(), Creature::is_npc(), pos(), and tripoint_zero.

Referenced by has_charges(), and symbol_color().

◆ has_grab_break_tec()

bool Character::has_grab_break_tec ( ) const
overridevirtual

Returns true if the player has a grab breaking technique available.

Implements Creature.

Definition at line 1197 of file martialarts.cpp.

1198{
1199 return martial_arts_data->has_grab_break_tec();
1200}

References martial_arts_data.

Referenced by can_use_grab_break_tec(), deal_damage(), and mattack::grab().

◆ has_item_with_flag()

bool Character::has_item_with_flag ( const std::string &  flag,
bool  need_charges = false 
) const

Definition at line 9537 of file character.cpp.

9538{
9539 return has_item_with( [&flag, &need_charges]( const item & it ) {
9540 if( it.is_tool() && need_charges ) {
9541 return it.has_flag( flag ) && it.type->tool->max_charges ? it.charges > 0 : it.has_flag( flag );
9542 }
9543 return it.has_flag( flag );
9544 } );
9545}

References item::has_flag(), visitable< Character >::has_item_with(), and item::is_tool().

Referenced by draw_env_compact(), draw_time_classic(), npc::faction_display(), get_temp(), has_alarm_clock(), has_fire(), has_watch(), loot(), overmap_sight_range(), monexamine::pet_menu(), npc::reach_omt_destination(), and use_fire().

◆ has_mabuff()

bool Character::has_mabuff ( const mabuff_id buff_id) const

Returns true if the player has any martial arts buffs attached.

Definition at line 1190 of file martialarts.cpp.

1191{
1192 return search_ma_buff_effect( *effects, [&id]( const ma_buff & b, const effect & ) {
1193 return b.id == id;
1194 } );
1195}
static bool search_ma_buff_effect(const C &container, F f)

References b, Creature::effects, id, and search_ma_buff_effect().

Referenced by ma_requirements::is_valid_character().

◆ has_max_power()

bool Character::has_max_power ( ) const

Definition at line 1932 of file character.cpp.

1933{
1934 return max_power_level > 0_kJ;
1935}

References max_power_level.

Referenced by bionics_install_failure(), has_bionics(), power_stat(), and suffer_from_bad_bionics().

◆ has_mission_item()

bool Character::has_mission_item ( int  mission_id) const

Definition at line 2494 of file character.cpp.

2495{
2496 return mission_id != -1 && has_item_with( has_mission_item_filter{ mission_id } );
2497}

References visitable< Character >::has_item_with().

◆ has_morale()

bool Character::has_morale ( const morale_type type) const

Definition at line 9058 of file character.cpp.

9059{
9060 return morale->has( type );
9061}

References morale, and type.

Referenced by ranged::fire_gun(), suffer_from_other_mutations(), and iuse::towel_common().

◆ has_morale_to_craft()

bool Character::has_morale_to_craft ( ) const

Definition at line 336 of file crafting.cpp.

337{
338 return get_morale_level() >= -50;
339}
int get_morale_level() const
Definition: character.cpp:9042

References get_morale_level().

Referenced by game::butcher(), veh_interact::cant_do(), and iuse::multicooker().

◆ has_morale_to_read()

bool Character::has_morale_to_read ( ) const

Definition at line 9078 of file character.cpp.

9079{
9080 return get_morale_level() >= -40;
9081}

References get_morale_level().

Referenced by avatar::get_book_reader().

◆ has_nv()

bool Character::has_nv ( )

Returns true if the player has some form of night vision.

Definition at line 3617 of file character.cpp.

3618{
3619 static bool nv = false;
3620
3621 if( !nv_cached ) {
3622 nv_cached = true;
3623 nv = ( worn_with_flag( flag_GNV_EFFECT ) ||
3626 }
3627
3628 return nv;
3629}
static const std::string flag_GNV_EFFECT("GNV_EFFECT")
static const std::string flag_EFFECT_NIGHT_VISION("EFFECT_NIGHT_VISION")
static const bionic_id bio_night_vision("bio_night_vision")

References bio_night_vision, flag_EFFECT_NIGHT_VISION(), flag_GNV_EFFECT(), has_active_bionic(), Creature::has_effect_with_flag(), nv_cached, and worn_with_flag().

Referenced by recalc_sight_limits().

◆ has_opposite_trait()

bool Character::has_opposite_trait ( const trait_id flag) const

Returns true if character has a trait which cancels the entered trait.

Definition at line 9872 of file character.cpp.

9873{
9874 for( const trait_id &i : flag->cancels ) {
9875 if( has_trait( i ) ) {
9876 return true;
9877 }
9878 }
9879 for( const std::pair<const trait_id, char_trait_data> &mut : my_mutations ) {
9880 for( const trait_id &canceled_trait : mut.first->cancels ) {
9881 if( canceled_trait == flag ) {
9882 return true;
9883 }
9884 }
9885 }
9886 return false;
9887}
std::vector< trait_id > cancels
Definition: mutation.h:262

References mutation_branch::cancels, has_trait(), and my_mutations.

Referenced by known_magic::can_learn_spell(), and newcharacter::has_conflicting_trait().

◆ has_power()

bool Character::has_power ( ) const

◆ has_stashed_activity()

bool Character::has_stashed_activity ( ) const

Definition at line 905 of file character.cpp.

906{
907 return static_cast<bool>( stashed_outbounds_activity );
908}

References stashed_outbounds_activity.

Referenced by npc::move().

◆ has_trait()

bool Character::has_trait ( const trait_id b) const
overridevirtual

Returns true if the player has the entered trait.

Reimplemented from Creature.

Definition at line 103 of file mutation.cpp.

104{
105 return my_mutations.count( b ) || enchantment_cache->get_mutations().count( b );
106}

References b, enchantment_cache, and my_mutations.

Referenced by absorb_hit(), activate_mutation(), add_addiction(), add_bionic(), character_funcs::add_pain_msg(), newcharacter::add_traits(), addict_effect(), adjust_for_focus(), alcohol(), allergy_type(), iuse::anticonvulsant(), iuse::antiparasitic(), apply_damage(), apply_persistent_morale(), monster::attitude(), iexamine::autodoc(), autodoc_internal(), iexamine::bars(), character_funcs::base_comfort_value(), basic_symbol_color(), bionics_pl_skill(), iuse::blech(), iuse::blood_draw(), bloodType(), activity_handlers::build_do_turn(), burn_move_stamina(), calc_all_parts_hp(), talk_trial::calc_chance(), character_effects::calc_focus_equilibrium(), calc_needs_rates(), player::can_continue_craft(), can_eat(), can_install_bionics(), spell::can_learn(), can_pick_weight(), npc::can_read(), cauterize_actor::can_use(), install_bionic_actor::can_use(), can_wear(), veh_interact::cant_do(), cauterize_actor::cauterize_effect(), iexamine::chainfence(), game::chat(), check_needs_extremes(), game::check_safe_mode_allowed(), game::cleanup_at_end(), item::color_in_inventory(), talk_function::commune_farmfield(), talk_function::companion_mission(), veh_interact::complete_vehicle(), construction_color(), consume_effects(), consume_item(), player::consume_items(), player::consume_tools(), iuse::contacts(), game::control_vehicle(), player::craft_consume_tools(), crafting_inventory(), player::crafting_success_roll(), avatar::create(), craft_command::create_in_progress_craft(), iuse::datura(), deal_damage(), debug_vision(), mattack::dermatik(), trap::detect_trap(), monster::die(), character_display::disp_info(), avatar::disp_morale(), veh_interact::do_mend(), do_purify(), game::do_turn(), construct::done_vehicle(), overmap_ui::draw_ascii(), draw_limb_health(), overmap_ui::draw_om_sidebar(), draw_speed_tab(), drench(), eat(), eff_fun_spores(), iuse::einktabletpc(), game::extended_description(), fall_damage_mod(), talk_function::field_harvest(), item::final_info(), game::find_or_make_stairs(), character_funcs::fine_detail_vision_mod(), npc::finish_read(), ranged::fire_gun(), floor_warmth(), iexamine::flower_dahlia(), item::food_info(), talk_function::forage_return(), npc::form_opinion(), fun_for(), fungal_effects::fungalize(), dialogue::gen_responses(), character_funcs::get_book_fun_for(), avatar::get_book_reader(), get_dodge(), get_env_resist(), get_face_type(), get_hunger_description(), character_funcs::get_lift_strength(), get_miss_reason(), npc::get_monster_faction(), overmap_ui::get_overmap_neighbors(), get_pain_description(), character_effects::get_pain_penalty(), get_shout_volume(), give_item_to(), avatar_funcs::gunmod_add(), avatar_funcs::gunmod_installation_odds(), game::handle_action(), hardcoded_effects(), hardcoded_mutation_attack(), iexamine::harvest_plant(), has_child_flag(), has_enough_anesth(), newcharacter::has_higher_trait(), newcharacter::has_lower_trait(), has_opposite_trait(), newcharacter::has_same_type_trait(), hearing_ability(), hit_roll(), hurtall(), in_climate_control(), install_bionics(), introduce_into_anesthesia(), irradiate(), character_funcs::is_bp_immune_to(), is_deaf(), item::is_filthy(), character_funcs::is_fun_to_read(), is_immune_damage(), is_immune_effect(), is_immune_field(), is_invisible(), wish_mutate_callback::key(), game::knockback(), talk_function::labor_return(), known_magic::learn_spell(), trapfunc::ledge(), iexamine::ledge(), player::load(), marloss_common(), marloss_prevented(), iuse::meditate(), melee_attack(), mend(), avatar_funcs::mend_item(), iuse::meth(), mod_pain(), modify_morale(), modify_stimulation(), game::mon_info_update(), avatar_action::move(), iuse::multicooker(), mutate(), mutate_category(), mutate_towards(), mutation_chances(), mutation_ok(), iuse::mycus(), old_mutate(), on_hit(), on_hurt(), npc::on_load(), map::open_door(), iexamine::pay_gas(), perform_install(), pick_part_to_heal(), activity_handlers::pickaxe_finish(), trapfunc::pit(), trapfunc::pit_glass(), trapfunc::pit_spikes(), game::place_player(), iuse::plantblech(), player_can_build(), player_can_see_to_build(), map::player_in_field(), iuse::poison(), iuse::portable_game(), practice(), print_health(), game::print_terrain_info(), process_effects_internal(), item::process_litcig(), process_one_effect(), sounds::process_sound_markers(), process_turn(), iuse::purify_iv(), iuse::purify_smart(), avatar::randomize(), npc::randomize(), character_funcs::rate_sleep_spot(), react_to_felt_pain(), avatar::read(), recalc_sight_limits(), recalc_speed_bonus(), wish_mutate_callback::refresh(), remove_child_flag(), remove_mutation(), reset_stats(), firestarter_actor::resolve_firestarter_use(), iuse::robotcontrol(), talk_trial::roll(), roll_bash_damage(), rooted(), rooted_message(), iexamine::rubble(), run_cost(), npc::say(), talk_function::scavenging_patrol_return(), sees_with_specials(), player::select_item_component(), conditional_t< T >::set_has_any_trait(), conditional_t< T >::set_has_trait(), set_traits(), shout(), iexamine::shrub_marloss(), sight_impaired(), iexamine::sign(), trapfunc::sinkhole(), game::slip_down(), stumble(), suffer(), suffer_from_addictions(), suffer_from_chemimbalance(), suffer_from_other_mutations(), suffer_from_radiation(), suffer_from_sunburn(), suffer_in_sunlight(), suffer_while_awake(), suffer_while_underwater(), swim_speed(), npc::talk_to_u(), test_crossing_threshold(), npc::time_to_read(), avatar::time_to_read(), avatar_funcs::toolmod_add(), iexamine::trap(), activity_handlers::tree_communion_do_turn(), iexamine::tree_marloss(), try_reject_mutagen(), try_start_hacking(), avatar_funcs::try_steal_from_npc(), avatar_funcs::try_to_sleep(), uninstall_bionic(), update_body(), character_funcs::update_body_wetness(), update_bodytemp(), update_needs(), veh_interact::update_part_requirements(), game::update_stair_monsters(), update_stomach(), consume_drug_iuse::use(), cauterize_actor::use(), enzlave_actor::use(), mutagen_actor::use(), mutagen_iv_actor::use(), game::use_computer(), game::vertical_move(), iuse::vibe(), volume_capacity_reduced_by(), character_effects::vomit_mod(), game::walk_move(), iuse::weed_cake(), weed_msg(), weight_capacity(), weather_effect::wet_player(), will_eat(), and debug_menu::wishmutate().

◆ has_trait_flag()

bool Character::has_trait_flag ( const std::string &  b) const

Returns true if player has a trait with a flag.

Definition at line 108 of file mutation.cpp.

109{
110 // UGLY, SLOW, should be cached as my_mutation_flags or something
111 for( const trait_id &mut : get_mutations() ) {
112 const mutation_branch &mut_data = mut.obj();
113 if( mut_data.flags.count( b ) > 0 ) {
114 return true;
115 }
116 }
117
118 return false;
119}
std::set< std::string > flags
Definition: mutation.h:266

References b, mutation_branch::flags, and get_mutations().

Referenced by consider_butchery(), do_skill_rust(), item::food_info(), mod_rad(), mod_thirst(), practice(), conditional_t< T >::set_has_trait_flag(), spell::spell_fail(), enzlave_actor::use(), and will_eat().

◆ has_two_arms()

bool Character::has_two_arms ( ) const

Returns true if the player has two functioning arms.

Returns true if the character has two functioning arms.

Definition at line 1201 of file character.cpp.

1202{
1203 return get_working_arm_count() >= 2;
1204}

References get_working_arm_count().

Referenced by can_wear(), can_wield(), ranged::gunmode_checks_common(), hardcoded_mutation_attack(), map::player_in_field(), and mattack::riotbot().

◆ has_watch()

bool Character::has_watch ( ) const

Returns true if the player or their vehicle has a watch.

Definition at line 717 of file character.cpp.

718{
719 map &here = get_map();
720 return ( has_item_with_flag( "WATCH", true ) ||
721 ( here.veh_at( pos() ) &&
722 !empty( here.veh_at( pos() )->vehicle().get_avail_parts( "WATCH" ) ) ) ||
724}

References bio_watch, get_map(), has_bionic(), has_item_with_flag(), pos(), map::veh_at(), and vehicle.

Referenced by draw_loc_labels(), draw_time(), draw_time_classic(), game::list_missions(), and wait().

◆ has_weapon()

bool Character::has_weapon ( ) const
overridevirtual

Implements Creature.

Definition at line 10325 of file character.cpp.

10326{
10327 return !unarmed_attack();
10328}
bool unarmed_attack() const
True if unarmed or wielding a weapon with the UNARMED_WEAPON flag.
Definition: melee.cpp:153

References unarmed_attack().

Referenced by perform_technique(), pick_technique(), and npc::talk_to_u().

◆ head_cloth_encumbrance()

int Character::head_cloth_encumbrance ( ) const

Returns the total encumbrance of all SKINTIGHT and HELMET_COMPAT items coveringi the head.

Definition at line 8866 of file character.cpp.

8867{
8868 int ret = 0;
8869 for( auto &i : worn ) {
8870 const item *worn_item = &i;
8871 if( i.covers( bp_head ) && !i.has_flag( flag_SEMITANGIBLE ) &&
8872 ( worn_item->has_flag( flag_HELMET_COMPAT ) || worn_item->has_flag( flag_SKINTIGHT ) ) ) {
8873 ret += worn_item->get_encumber( *this );
8874 }
8875 }
8876 return ret;
8877}

References bp_head, flag_HELMET_COMPAT(), flag_SEMITANGIBLE(), flag_SKINTIGHT(), item::get_encumber(), item::has_flag(), cata::hash64_detail::ret, and worn.

Referenced by can_wear().

◆ heal()

void Character::heal ( const bodypart_id healed,
int  dam 
)

Heals a body_part for dam.

Definition at line 8600 of file character.cpp.

8601{
8602 if( !is_limb_broken( healed ) ) {
8603 int effective_heal = std::min( dam, get_part_hp_max( healed ) - get_part_hp_cur( healed ) );
8604 mod_part_hp_cur( healed, effective_heal );
8605 g->events().send<event_type::character_heals_damage>( getID(), effective_heal );
8606 }
8607}
@ character_heals_damage

References character_heals_damage, g, Creature::get_part_hp_cur(), Creature::get_part_hp_max(), getID(), is_limb_broken(), and Creature::mod_part_hp_cur().

Referenced by enforce_minimum_healing(), heal_actor::finish_using(), give_aid_to(), healall(), process_bionic(), regen(), and suffer_water_damage().

◆ healall()

void Character::healall ( int  dam)

Heals all body parts for dam.

Definition at line 8609 of file character.cpp.

8610{
8611 for( const bodypart_id &bp : get_all_body_parts() ) {
8612 heal( bp, dam );
8613 mod_part_healed_total( bp, dam );
8614 }
8615}
void mod_part_healed_total(const bodypart_id &id, int mod)
Definition: creature.cpp:1606

References Creature::get_all_body_parts(), heal(), and Creature::mod_part_healed_total().

Referenced by iuse::artifact(), consume_effects(), hardcoded_effects(), spell::heal(), iuse::jet_injector(), melee_attack(), iuse::mycus(), regen(), and suffer_from_radiation().

◆ healed_bp()

void Character::healed_bp ( int  bp,
int  amount 
)

Definition at line 7701 of file character.cpp.

7702{
7703 healed_total[bp] += amount;
7704}

References healed_total.

Referenced by regen().

◆ healing_rate()

float Character::healing_rate ( float  at_rest_quality) const

Average hit points healed per turn.

Definition at line 6618 of file character.cpp.

6619{
6620 // TODO: Cache
6621 float heal_rate;
6622 if( !is_npc() ) {
6623 heal_rate = get_option< float >( "PLAYER_HEALING_RATE" );
6624 } else {
6625 heal_rate = get_option< float >( "NPC_HEALING_RATE" );
6626 }
6627 float awake_rate = heal_rate * mutation_value( "healing_awake" );
6628 float final_rate = 0.0f;
6629 if( awake_rate > 0.0f ) {
6630 final_rate += awake_rate;
6631 } else if( at_rest_quality < 1.0f ) {
6632 // Resting protects from rot
6633 final_rate += ( 1.0f - at_rest_quality ) * awake_rate;
6634 }
6635 float asleep_rate = 0.0f;
6636 if( at_rest_quality > 0.0f ) {
6637 asleep_rate = at_rest_quality * heal_rate * ( 1.0f + mutation_value( "healing_resting" ) );
6638 }
6639 if( asleep_rate > 0.0f ) {
6640 final_rate += asleep_rate * ( 1.0f + get_healthy() / 200.0f );
6641 }
6642
6643 // Most common case: awake player with no regenerative abilities
6644 // ~7e-5 is 1 hp per day, anything less than that is totally negligible
6645 static constexpr float eps = 0.000007f;
6646 add_msg( m_debug, "%s healing: %.6f", name, final_rate );
6647 if( std::abs( final_rate ) < eps ) {
6648 return 0.0f;
6649 }
6650
6651 float primary_hp_mod = mutation_value( "hp_modifier" );
6652 if( primary_hp_mod < 0.0f ) {
6653 // HP mod can't get below -1.0
6654 final_rate *= 1.0f + primary_hp_mod;
6655 }
6656
6657 return final_rate;
6658}

References add_msg(), get_healthy(), Creature::is_npc(), m_debug, mutation_value(), and name.

Referenced by regen().

◆ healing_rate_medicine()

float Character::healing_rate_medicine ( float  at_rest_quality,
const bodypart_id bp 
) const

Average hit points healed per turn from healing effects.

Definition at line 6660 of file character.cpp.

6661{
6662 float rate_medicine = 0.0f;
6663 float bandaged_rate = 0.0f;
6664 float disinfected_rate = 0.0f;
6665
6666 const effect &e_bandaged = get_effect( effect_bandaged, bp->token );
6667 const effect &e_disinfected = get_effect( effect_disinfected, bp->token );
6668
6669 if( !e_bandaged.is_null() ) {
6670 bandaged_rate += static_cast<float>( e_bandaged.get_amount( "HEAL_RATE" ) ) / to_turns<int>
6671 ( 24_hours );
6672 if( bp == bodypart_id( "head" ) ) {
6673 bandaged_rate *= e_bandaged.get_amount( "HEAL_HEAD" ) / 100.0f;
6674 }
6675 if( bp == bodypart_id( "torso" ) ) {
6676 bandaged_rate *= e_bandaged.get_amount( "HEAL_TORSO" ) / 100.0f;
6677 }
6678 }
6679
6680 if( !e_disinfected.is_null() ) {
6681 disinfected_rate += static_cast<float>( e_disinfected.get_amount( "HEAL_RATE" ) ) / to_turns<int>
6682 ( 24_hours );
6683 if( bp == bodypart_id( "head" ) ) {
6684 disinfected_rate *= e_disinfected.get_amount( "HEAL_HEAD" ) / 100.0f;
6685 }
6686 if( bp == bodypart_id( "torso" ) ) {
6687 disinfected_rate *= e_disinfected.get_amount( "HEAL_TORSO" ) / 100.0f;
6688 }
6689 }
6690
6691 rate_medicine += bandaged_rate + disinfected_rate;
6692 rate_medicine *= 1.0f + mutation_value( "healing_resting" );
6693 rate_medicine *= 1.0f + at_rest_quality;
6694
6695 // increase healing if character has both effects
6696 if( !e_bandaged.is_null() && !e_disinfected.is_null() ) {
6697 rate_medicine *= 2;
6698 }
6699
6700 if( get_healthy() > 0.0f ) {
6701 rate_medicine *= 1.0f + get_healthy() / 200.0f;
6702 } else {
6703 rate_medicine *= 1.0f + get_healthy() / 400.0f;
6704 }
6705 float primary_hp_mod = mutation_value( "hp_modifier" );
6706 if( primary_hp_mod < 0.0f ) {
6707 // HP mod can't get below -1.0
6708 rate_medicine *= 1.0f + primary_hp_mod;
6709 }
6710 return rate_medicine;
6711}
int get_amount(std::string arg, bool reduced=false) const
Returns the amount of a modifier type applied when a new effect is first added.
Definition: effect.cpp:974

References effect_bandaged, effect_disinfected, effect::get_amount(), Creature::get_effect(), get_healthy(), effect::is_null(), and mutation_value().

Referenced by regen().

◆ hearing_ability()

float Character::hearing_ability ( ) const

Definition at line 10250 of file character.cpp.

10251{
10252 float volume_multiplier = 1.0;
10253
10254 // Mutation/Bionic volume modifiers
10256 volume_multiplier *= 3.5;
10257 }
10258 if( has_trait( trait_PER_SLIME ) ) {
10259 // Random hearing :-/
10260 // (when it's working at all, see player.cpp)
10261 // changed from 0.5 to fix Mac compiling error
10262 volume_multiplier *= ( rng( 1, 2 ) );
10263 }
10264
10265 volume_multiplier *= Character::mutation_value( "hearing_modifier" );
10266
10267 if( has_effect( effect_deaf ) ) {
10268 // Scale linearly up to 30 minutes
10269 volume_multiplier *= ( 30_minutes - get_effect_dur( effect_deaf ) ) / 30_minutes;
10270 }
10271
10272 if( has_effect( effect_earphones ) ) {
10273 volume_multiplier *= .25;
10274 }
10275
10276 return volume_multiplier;
10277}
static const trait_id trait_PER_SLIME("PER_SLIME")
static const efftype_id effect_deaf("deaf")
static const bionic_id bio_ears("bio_ears")
static const bionic_id bio_earplugs("bio_earplugs")
static const efftype_id effect_earphones("earphones")

References bio_earplugs, bio_ears, effect_deaf, effect_earphones, Creature::get_effect_dur(), has_active_bionic(), Creature::has_effect(), has_trait(), mutation_value(), rng(), and trait_PER_SLIME.

Referenced by can_hear(), and sounds::process_sound_markers().

◆ heat_emission()

void Character::heat_emission ( bionic bio,
int  fuel_energy 
)

Handle heat from exothermic power generation.

Definition at line 1452 of file bionics.cpp.

1453{
1454 if( !bio.info().exothermic_power_gen ) {
1455 return;
1456 }
1457 const float efficiency = bio.info().fuel_efficiency;
1458
1459 const int heat_prod = fuel_energy * ( 1.0f - efficiency );
1460 const int heat_level = std::min( heat_prod / 10, 4 );
1461 const emit_id hotness = emit_id( "emit_hot_air" + std::to_string( heat_level ) + "_cbm" );
1462 map &here = get_map();
1463 if( hotness.is_valid() ) {
1464 const int heat_spread = std::max( heat_prod / 10 - heat_level, 1 );
1465 here.emit_field( pos(), hotness, heat_spread );
1466 }
1467 for( const std::pair<const bodypart_str_id, int> &bp : bio.info().occupied_bodyparts ) {
1468 add_effect( effect_heating_bionic, 2_seconds, bp.first->token, heat_prod );
1469 }
1470}
static const efftype_id effect_heating_bionic("heating_bionic")
bool exothermic_power_gen
If true this bionic emits heat when producing power.
Definition: bionics.h:75
string_id< emit > emit_id
Definition: type_id.h:51

References Creature::add_effect(), effect_heating_bionic, map::emit_field(), bionic_data::exothermic_power_gen, bionic_data::fuel_efficiency, get_map(), bionic::info(), string_id< T >::is_valid(), bionic_data::occupied_bodyparts, pos(), and to_string().

Referenced by burn_fuel(), and passive_power_gen().

◆ height()

int Character::height ( ) const

Definition at line 6799 of file character.cpp.

6800{
6801 switch( get_size() ) {
6802 case MS_TINY:
6803 return init_height - 100;
6804 case MS_SMALL:
6805 return init_height - 50;
6806 case MS_MEDIUM:
6807 return init_height;
6808 case MS_LARGE:
6809 return init_height + 50;
6810 case MS_HUGE:
6811 return init_height + 100;
6812 default:
6813 break;
6814 }
6815
6816 debugmsg( "Invalid size class" );
6817 abort();
6818}
@ MS_TINY
Definition: creature.h:58
@ MS_LARGE
Definition: creature.h:61
@ MS_SMALL
Definition: creature.h:59
@ MS_HUGE
Definition: creature.h:62
@ MS_MEDIUM
Definition: creature.h:60

References abort, debugmsg, get_size(), init_height, MS_HUGE, MS_LARGE, MS_MEDIUM, MS_SMALL, and MS_TINY.

Referenced by bodyweight(), height_string(), and set_base_height().

◆ height_string()

std::string Character::height_string ( ) const

Definition at line 6784 of file character.cpp.

6785{
6786 const bool metric = get_option<std::string>( "DISTANCE_UNITS" ) == "metric";
6787
6788 if( metric ) {
6789 std::string metric_string = _( "%d cm" );
6790 return string_format( metric_string, height() );
6791 }
6792
6793 int total_inches = std::round( height() / 2.54 );
6794 int feet = std::floor( total_inches / 12 );
6795 int remainder_inches = total_inches % 12;
6796 return string_format( "%d\'%d\"", feet, remainder_inches );
6797}

References _, height(), and string_format().

Referenced by draw_stats_info(), and draw_stats_tab().

◆ hit_roll()

float Character::hit_roll ( ) const
overridevirtual

Returns the player's basic hit roll that is compared to the target's dodge roll.

Implements Creature.

Definition at line 300 of file melee.cpp.

301{
302 // Dexterity, skills, weapon and martial arts
303 float hit = get_melee_hit_base();
304
305 // Farsightedness makes us hit worse
306 if( has_trait( trait_HYPEROPIC ) && !worn_with_flag( "FIX_FARSIGHT" ) &&
308 hit -= 2.0f;
309 }
310
311 //Unstable ground chance of failure
313 hit *= 0.75f;
314 }
315
316 hit *= std::max( 0.25f, 1.0f - encumb( bp_torso ) / 100.0f );
317
318 return melee::melee_hit_range( hit );
319}
float get_melee_hit_base() const
Returns weapon skill.
Definition: melee.cpp:294
float melee_hit_range(float accuracy)
Once the accuracy (sum of modifiers) of an attack has been determined, this is used to actually roll ...
Definition: melee.cpp:2442

References bp_torso, effect_bouldering, effect_contacts, encumb(), get_melee_hit_base(), Creature::has_effect(), has_trait(), melee::melee_hit_range(), trait_HYPEROPIC, and worn_with_flag().

Referenced by melee_attack(), perform_special_attacks(), scored_crit(), and avatar_funcs::try_disarm_npc().

◆ hitall()

int Character::hitall ( int  dam,
int  vary,
Creature source 
)

Harms all body parts for dam, with armor reduction.

If vary > 0 damage to parts are random within vary % (1-100)

Definition at line 8635 of file character.cpp.

8636{
8637 int damage_taken = 0;
8638 for( int i = 0; i < num_hp_parts; i++ ) {
8639 const bodypart_id bp = convert_bp( hp_to_bp( static_cast<hp_part>( i ) ) ).id();
8640 int ddam = vary ? dam * rng( 100 - vary, 100 ) / 100 : dam;
8641 int cut = 0;
8642 auto damage = damage_instance::physical( ddam, cut, 0 );
8643 damage_taken += deal_damage( source, bp, damage ).total_damage();
8644 }
8645 return damage_taken;
8646}
static body_part hp_to_bp(hp_part hpart)
Converts an hp_part to a body_part.
Definition: character.cpp:6443
int_id< T > id() const
Translate the string based it to the matching integer based id.
Definition: ammo_effect.cpp:54

References convert_bp(), deal_damage(), hp_to_bp(), string_id< T >::id(), num_hp_parts, damage_instance::physical(), rng(), and dealt_damage_instance::total_damage().

Referenced by game::forced_door_closing(), and vehicle::part_collision().

◆ hp_percentage()

int Character::hp_percentage ( ) const
overridevirtual

Returns overall % of HP remaining.

Implements Creature.

Definition at line 10858 of file character.cpp.

10859{
10860 const bodypart_id head_id = bodypart_id( "head" );
10861 const bodypart_id torso_id = bodypart_id( "torso" );
10862 int total_cur = 0;
10863 int total_max = 0;
10864 // Head and torso HP are weighted 3x and 2x, respectively
10865 total_cur = get_part_hp_cur( head_id ) * 3 + get_part_hp_cur( torso_id ) * 2;
10866 total_max = get_part_hp_max( head_id ) * 3 + get_part_hp_max( torso_id ) * 2;
10867 for( const std::pair< const bodypart_str_id, bodypart> &elem : get_body() ) {
10868 total_cur += elem.second.get_hp_cur();
10869 total_max += elem.second.get_hp_max();
10870 }
10871
10872 return ( 100 * total_cur ) / total_max;
10873}

References Creature::get_body(), Creature::get_part_hp_cur(), and Creature::get_part_hp_max().

Referenced by npc::character_danger(), npc::emergency(), npc::hp_description(), and npc::process_turn().

◆ hp_to_bp()

body_part Character::hp_to_bp ( hp_part  hpart)
static

Converts an hp_part to a body_part.

Definition at line 6443 of file character.cpp.

6444{
6445 switch( hpart ) {
6446 case hp_head:
6447 return bp_head;
6448 case hp_torso:
6449 return bp_torso;
6450 case hp_arm_l:
6451 return bp_arm_l;
6452 case hp_arm_r:
6453 return bp_arm_r;
6454 case hp_leg_l:
6455 return bp_leg_l;
6456 case hp_leg_r:
6457 return bp_leg_r;
6458 default:
6459 return num_bp;
6460 }
6461}

References bp_arm_l, bp_arm_r, bp_head, bp_leg_l, bp_leg_r, bp_torso, hp_arm_l, hp_arm_r, hp_head, hp_leg_l, hp_leg_r, hp_torso, and num_bp.

Referenced by iexamine::autodoc(), cauterize_actor::cauterize_effect(), draw_limb_health(), heal_actor::finish_using(), hitall(), impact(), pick_part_to_heal(), map::player_in_field(), regen(), heal_actor::use_healing_item(), and npc::wear_if_wanted().

◆ hurtall()

void Character::hurtall ( int  dam,
Creature source,
bool  disturb = true 
)

Hurts all body parts for dam, no armor reduction.

Definition at line 8617 of file character.cpp.

8618{
8619 if( is_dead_state() || has_trait( trait_DEBUG_NODMG ) || dam <= 0 ) {
8620 return;
8621 }
8622
8623 for( const bodypart_id &bp : get_all_body_parts( true ) ) {
8624 // Don't use apply_damage here or it will annoy the player with 6 queries
8625 const int dam_to_bodypart = std::min( dam, get_part_hp_cur( bp ) );
8626 mod_part_hp_cur( bp, - dam_to_bodypart );
8627 g->events().send<event_type::character_takes_damage>( getID(), dam_to_bodypart );
8628 }
8629
8630 // Low pain: damage is spread all over the body, so not as painful as 6 hits in one part
8631 mod_pain( dam );
8632 on_hurt( source, disturb );
8633}

References character_takes_damage, g, Creature::get_all_body_parts(), Creature::get_part_hp_cur(), getID(), has_trait(), is_dead_state(), mod_pain(), Creature::mod_part_hp_cur(), on_hurt(), and trait_DEBUG_NODMG.

Referenced by trapfunc::drain(), hardcoded_effects(), marloss_common(), trapfunc::pit(), map::player_in_field(), game::process_artifact(), relic_funcs::process_recharge_entry(), regen(), map::shake_vehicle(), suffer_from_bad_bionics(), suffer_from_radiation(), trapfunc::tripwire(), and try_reject_mutagen().

◆ i_add()

item & Character::i_add ( item  it,
bool  should_stack = true 
)

Definition at line 2239 of file character.cpp.

2240{
2241 itype_id item_type_id = it.typeId();
2242 last_item = item_type_id;
2243
2244 if( it.is_food() || it.is_ammo() || it.is_gun() || it.is_armor() ||
2245 it.is_book() || it.is_tool() || it.is_melee() || it.is_food_container() ) {
2246 inv.unsort();
2247 }
2248
2249 // if there's a desired invlet for this item type, try to use it
2250 bool keep_invlet = false;
2251 const invlets_bitset cur_inv = allocated_invlets();
2252 for( auto iter : inv.assigned_invlet ) {
2253 if( iter.second == item_type_id && !cur_inv[iter.first] ) {
2254 it.invlet = iter.first;
2255 keep_invlet = true;
2256 break;
2257 }
2258 }
2259 auto &item_in_inv = inv.add_item( it, keep_invlet, true, should_stack );
2260 item_in_inv.on_pickup( *this );
2261 clear_npc_ai_info_cache( "reloadables" );
2262 return item_in_inv;
2263}
itype_id last_item
Definition: character.h:1545
std::bitset< std::numeric_limits< char >::max()> allocated_invlets() const
Only use for UI things.
Definition: character.cpp:2465
void clear_npc_ai_info_cache(const std::string &key) const
std::map< char, itype_id > assigned_invlet
Definition: inventory.h:99
bool is_gun() const
Can this item be used to perform a ranged attack?
Definition: item.cpp:6522
bool is_food_container() const
Definition: item.cpp:6613
bool is_book() const
Definition: item.cpp:6714
void on_pickup(Character &p)
Callback when a player starts carrying the item.
Definition: item.cpp:4508
bool is_melee(damage_type dt) const
Is this item an effective melee weapon for the given damage type?
Definition: item.cpp:6682

References inventory::add_item(), allocated_invlets(), inventory::assigned_invlet, clear_npc_ai_info_cache(), inv, item::invlet, item::is_ammo(), item::is_armor(), item::is_book(), item::is_food(), item::is_food_container(), item::is_gun(), item::is_melee(), item::is_tool(), last_item, item::on_pickup(), item::typeId(), and inventory::unsort().

Referenced by avatar_funcs::add_or_drop_with_msg(), iuse::adrenaline_injector(), iuse::arrow_flammable(), monexamine::attach_or_remove_saddle(), debug_menu::debug(), fetch_activity(), give_item_to(), handle_harvest(), i_add_or_drop(), mount_creature(), npc::mug_player(), iuse::multicooker(), item_location::impl::item_on_map::obtain(), item_location::impl::item_on_person::obtain(), item_location::impl::item_on_vehicle::obtain(), item_location::impl::item_in_container::obtain(), pick_one_up(), npc::pick_up_item(), iuse::purify_smart(), iuse::radiocar(), item::reload(), monexamine::remove_leash(), mattack::riotbot(), talk_effect_fun_t::set_bulk_trade_accept(), set_item_inventory(), talk_effect_fun_t::set_u_buy_item(), talk_effect_fun_t::set_u_sell_item(), gun_actor::shoot(), spell_effect::spawn_ethereal_item(), npc::stow_item(), npc_trading::transfer_items(), avatar_funcs::try_steal_from_npc(), ammobelt_actor::use(), iuse::vaccine(), and avatar_action::wield().

◆ i_add_or_drop()

bool Character::i_add_or_drop ( item it,
int  qty = 1 
)

Sets invlet and adds to inventory if possible, drops otherwise, returns true if either succeeded.

An optional qty can be provided (and will perform better than separate calls).

Definition at line 2377 of file character.cpp.

2378{
2379 bool retval = true;
2380 bool drop = it.made_of( LIQUID );
2381 bool add = it.is_gun() || !it.is_irremovable();
2382 inv.assign_empty_invlet( it, *this );
2383 map &here = get_map();
2384 for( int i = 0; i < qty; ++i ) {
2385 drop |= !can_pick_weight( it, !get_option<bool>( "DANGEROUS_PICKUPS" ) ) || !can_pick_volume( it );
2386 if( drop ) {
2387 retval &= !here.add_item_or_charges( pos(), it ).is_null();
2388 } else if( add ) {
2389 i_add( it );
2390 }
2391 }
2392
2393 return retval;
2394}
item & i_add(item it, bool should_stack=true)
Definition: character.cpp:2239
bool can_pick_volume(const item &it) const
Definition: character.cpp:2675
void assign_empty_invlet(item &it, const Character &p, bool force=false)
Definition: inventory.cpp:1151
bool is_irremovable() const
Definition: item.cpp:6780
type add(type dir1, type dir2)
Returns a sum of two numbers.
Definition: overmap.cpp:4193

References om_direction::add(), map::add_item_or_charges(), inventory::assign_empty_invlet(), can_pick_volume(), can_pick_weight(), drop(), get_map(), i_add(), inv, item::is_gun(), item::is_irremovable(), item::is_null(), LIQUID, item::made_of(), and pos().

Referenced by activate_mutation(), salvage_actor::cut_up(), drop_or_handle(), heal_actor::finish_using(), avatar_funcs::gunmod_remove(), item_contents::handle_liquid_or_spill(), iexamine::pedestal_wyrm(), item::reload(), remove_radio_mod(), avatar_funcs::unload_item(), consume_drug_iuse::use(), bandolier_actor::use(), iexamine::vending(), and debug_menu::wishitem().

◆ i_add_to_container()

int Character::i_add_to_container ( const item it,
bool  unloading 
)

Try to find a container/s on character containing ammo of type it.typeId() and add charges until the container is full.

Parameters
unloadingDo not try to add to a container when the item was intentionally unloaded.
Returns
Remaining charges which could not be stored in a container.

Definition at line 2203 of file character.cpp.

2204{
2205 int charges = it.charges;
2206 if( !it.is_ammo() || unloading ) {
2207 return charges;
2208 }
2209
2210 const itype_id item_type = it.typeId();
2211 auto add_to_container = [&it, &charges]( item & container ) {
2212 auto &contained_ammo = container.contents.front();
2213 if( contained_ammo.charges < container.ammo_capacity() ) {
2214 const int diff = container.ammo_capacity() - contained_ammo.charges;
2215 //~ %1$s: item name, %2$s: container name
2216 add_msg( pgettext( "container", "You put the %1$s in your %2$s." ), it.tname(), container.tname() );
2217 if( diff > charges ) {
2218 contained_ammo.charges += charges;
2219 return 0;
2220 } else {
2221 contained_ammo.charges = container.ammo_capacity();
2222 return charges - diff;
2223 }
2224 }
2225 return charges;
2226 };
2227
2228 visit_items( [ & ]( item * item ) {
2229 if( charges > 0 && item->is_ammo_container() && item_type == item->contents.front().typeId() ) {
2230 charges = add_to_container( *item );
2231 item->handle_pickup_ownership( *this );
2232 }
2233 return VisitResponse::NEXT;
2234 } );
2235
2236 return charges;
2237}
bool is_ammo_container() const
Definition: item.cpp:6667
VisitResponse visit_items(const std::function< VisitResponse(item *, item *)> &func)
Traverses this object and any child items contained using a visitor pattern.
Definition: visitable.cpp:422

References add_msg(), item::charges, item::contents, item_contents::front(), item::is_ammo(), item::is_ammo_container(), NEXT, pgettext(), item::tname(), item::typeId(), and visitable< Character >::visit_items().

Referenced by avatar_funcs::add_or_drop_with_msg(), and pick_one_up().

◆ i_at() [1/2]

◆ i_at() [2/2]

const item & Character::i_at ( int  position) const

Definition at line 2303 of file character.cpp.

2304{
2305 if( position == -1 ) {
2306 return weapon;
2307 }
2308 if( position < -1 ) {
2309 int worn_index = worn_position_to_index( position );
2310 if( static_cast<size_t>( worn_index ) < worn.size() ) {
2311 auto iter = worn.begin();
2312 std::advance( iter, worn_index );
2313 return *iter;
2314 }
2315 }
2316
2317 return inv.find_item( position );
2318}
const item & find_item(int position) const
Definition: inventory.cpp:800

References inventory::find_item(), inv, position, weapon, worn, and worn_position_to_index().

◆ i_rem() [1/2]

item Character::i_rem ( const item it)

Remove a specific item from player possession.

The item is compared by pointer. Contents of the item are removed as well.

Parameters
itA pointer to the item to be removed. The item must exists in the players possession (one can use has_item to check for this).
Returns
A copy of the removed item.

Definition at line 2360 of file character.cpp.

2361{
2362 auto tmp = remove_items_with( [&it]( const item & i ) {
2363 return &i == it;
2364 }, 1 );
2365 if( tmp.empty() ) {
2366 debugmsg( "did not found item %s to remove it!", it->tname() );
2367 return item();
2368 }
2369 return tmp.front();
2370}
std::list< item > remove_items_with(const std::function< bool(const item &)> &filter, int count=INT_MAX)
Removes items contained by this instance which match the filter.

References debugmsg, visitable< Character >::remove_items_with(), and item::tname().

◆ i_rem() [2/2]

item Character::i_rem ( int  pos)

Remove a specific item from player possession.

The item is compared by pointer. Contents of the item are removed as well.

Parameters
posThe item position of the item to be removed. The item must exists, use has_item to check this.
Returns
A copy of the removed item.

Definition at line 2342 of file character.cpp.

2343{
2344 item tmp;
2345 if( pos == -1 ) {
2346 tmp = weapon;
2347 weapon = item();
2348 return tmp;
2349 } else if( pos < -1 && pos > worn_position_to_index( worn.size() ) ) {
2350 auto iter = worn.begin();
2351 std::advance( iter, worn_position_to_index( pos ) );
2352 tmp = *iter;
2353 tmp.on_takeoff( *this );
2354 worn.erase( iter );
2355 return tmp;
2356 }
2357 return inv.remove_item( pos );
2358}

References inv, item::on_takeoff(), pos(), inventory::remove_item(), weapon, worn, and worn_position_to_index().

Referenced by monexamine::add_leash(), apply_damage(), monexamine::attach_bag_to(), mattack::bio_op_disarm(), iuse::blood_draw(), consume(), consume_charges(), drop_invalid_inventory(), npc::drop_items(), iuse::fish_trap(), give_item_to(), activity_handlers::gunmod_add_finish(), ranged::handle_gun_damage(), i_rem_keep_contents(), monexamine::insert_battery(), invoke_item(), activity_handlers::lockpicking_finish(), iuse::lumber(), npc::mug_player(), npc_throw(), pickup::obtain_and_tokenize_items(), iuse::radiocar(), player::reduce_charges(), character_funcs::store_in_container(), tidy_activity(), avatar_funcs::try_disarm_npc(), avatar_funcs::try_steal_from_npc(), unpack_actor::use(), and avatar::wield().

◆ i_rem_keep_contents()

void Character::i_rem_keep_contents ( int  idx)

Definition at line 2372 of file character.cpp.

2373{
2374 i_rem( idx ).spill_contents( pos() );
2375}

References i_rem(), pos(), and item::spill_contents().

Referenced by damage_item(), and sew_advanced_actor::use().

◆ impact()

int Character::impact ( int  force,
const tripoint pos 
)
overridevirtual

Deals falling/collision damage with terrain/creature at pos.

Implements Creature.

Definition at line 10649 of file character.cpp.

10650{
10651 // Falls over ~30m are fatal more often than not
10652 // But that would be quite a lot considering 21 z-levels in game
10653 // so let's assume 1 z-level is comparable to 30 force
10654
10655 if( force <= 0 ) {
10656 return force;
10657 }
10658
10659 // Damage modifier (post armor)
10660 float mod = 1.0f;
10661 int effective_force = force;
10662 int cut = 0;
10663 // Percentage armor penetration - armor won't help much here
10664 // TODO: Make cushioned items like bike helmets help more
10665 float armor_eff = 1.0f;
10666 // Shock Absorber CBM heavily reduces damage
10667 const bool shock_absorbers = has_active_bionic( bionic_id( "bio_shock_absorber" ) );
10668
10669 // Being slammed against things rather than landing means we can't
10670 // control the impact as well
10671 const bool slam = p != pos();
10672 std::string target_name = "a swarm of bugs";
10673 Creature *critter = g->critter_at( p );
10674 if( critter != this && critter != nullptr ) {
10675 target_name = critter->disp_name();
10676 // Slamming into creatures and NPCs
10677 // TODO: Handle spikes/horns and hard materials
10678 armor_eff = 0.5f; // 2x as much as with the ground
10679 // TODO: Modify based on something?
10680 mod = 1.0f;
10681 effective_force = force;
10682 } else if( const optional_vpart_position vp = g->m.veh_at( p ) ) {
10683 // Slamming into vehicles
10684 // TODO: Integrate it with vehicle collision function somehow
10685 target_name = vp->vehicle().disp_name();
10686 if( vp.part_with_feature( "SHARP", true ) ) {
10687 // Now we're actually getting impaled
10688 cut = force; // Lots of fun
10689 }
10690
10691 mod = slam ? 1.0f : fall_damage_mod();
10692 armor_eff = 0.25f; // Not much
10693 if( !slam && vp->part_with_feature( "ROOF", true ) ) {
10694 // Roof offers better landing than frame or pavement
10695 // TODO: Make this not happen with heavy duty/plated roof
10696 effective_force /= 2;
10697 }
10698 } else {
10699 // Slamming into terrain/furniture
10700 target_name = g->m.disp_name( p );
10701 int hard_ground = g->m.has_flag( TFLAG_DIGGABLE, p ) ? 0 : 3;
10702 armor_eff = 0.25f; // Not much
10703 // Get cut by stuff
10704 // This isn't impalement on metal wreckage, more like flying through a closed window
10705 cut = g->m.has_flag( TFLAG_SHARP, p ) ? 5 : 0;
10706 effective_force = force + hard_ground;
10707 mod = slam ? 1.0f : fall_damage_mod();
10708 if( g->m.has_furn( p ) ) {
10709 // TODO: Make furniture matter
10710 } else if( g->m.has_flag( TFLAG_SWIMMABLE, p ) ) {
10711 // TODO: Some formula of swimming
10712 effective_force /= 4;
10713 }
10714 }
10715
10716 // Rescale for huge force
10717 // At >30 force, proper landing is impossible and armor helps way less
10718 if( effective_force > 30 ) {
10719 // Armor simply helps way less
10720 armor_eff *= 30.0f / effective_force;
10721 if( mod < 1.0f ) {
10722 // Everything past 30 damage gets a worse modifier
10723 const float scaled_mod = std::pow( mod, 30.0f / effective_force );
10724 const float scaled_damage = ( 30.0f * mod ) + scaled_mod * ( effective_force - 30.0f );
10725 mod = scaled_damage / effective_force;
10726 }
10727 }
10728
10729 if( !slam && mod < 1.0f && mod * force < 5 ) {
10730 // Perfect landing, no damage (regardless of armor)
10731 add_msg_if_player( m_warning, _( "You land on %s." ), target_name );
10732 return 0;
10733 }
10734
10735 // Shock absorbers kick in only when they need to, so if our other protections fail, fall back on them
10736 if( shock_absorbers ) {
10737 effective_force -= 15; // Provide a flat reduction to force
10738 if( mod > 0.25f ) {
10739 mod = 0.25f; // And provide a 75% reduction against that force if we don't have it already
10740 }
10741 if( effective_force < 0 ) {
10742 effective_force = 0;
10743 }
10744 }
10745
10746 int total_dealt = 0;
10747 if( mod * effective_force >= 5 ) {
10748 for( int i = 0; i < num_hp_parts; i++ ) {
10749 const bodypart_id bp = convert_bp( hp_to_bp( static_cast<hp_part>( i ) ) ).id();
10750 const int bash = effective_force * rng( 60, 100 ) / 100;
10751 damage_instance di;
10752 di.add_damage( DT_BASH, bash, 0, armor_eff, mod );
10753 // No good way to land on sharp stuff, so here modifier == 1.0f
10754 di.add_damage( DT_CUT, cut, 0, armor_eff, 1.0f );
10755 total_dealt += deal_damage( nullptr, bp, di ).total_damage();
10756 }
10757 }
10758
10759 if( total_dealt > 0 && is_player() ) {
10760 // "You slam against the dirt" is fine
10761 add_msg( m_bad, _( "You are slammed against %1$s for %2$d damage." ),
10762 target_name, total_dealt );
10763 } else if( is_player() && shock_absorbers ) {
10764 add_msg( m_bad, _( "You are slammed against %s!" ),
10765 target_name, total_dealt );
10766 add_msg( m_good, _( "…but your shock absorbers negate the damage!" ) );
10767 } else if( slam ) {
10768 // Only print this line if it is a slam and not a landing
10769 // Non-players should only get this one: player doesn't know how much damage was dealt
10770 // and landing messages for each slammed creature would be too much
10772 _( "You are slammed against %s." ),
10773 _( "<npcname> is slammed against %s." ),
10774 target_name );
10775 } else {
10776 // No landing message for NPCs
10777 add_msg_if_player( m_warning, _( "You land on %s." ), target_name );
10778 }
10779
10780 if( x_in_y( mod, 1.0f ) ) {
10781 add_effect( effect_downed, rng( 1_turns, 1_turns + mod * 3_turns ) );
10782 }
10783
10784 return total_dealt;
10785}
float fall_damage_mod() const override
Returns multiplier on fall damage at low velocity (knockback/pit/1 z-level, not 5 z-levels)
@ TFLAG_DIGGABLE
Definition: mapdata.h:297
@ TFLAG_SWIMMABLE
Definition: mapdata.h:279
@ TFLAG_SHARP
Definition: mapdata.h:296
void bash(const spell &sp, Creature &caster, const tripoint &target)

References _, damage_instance::add_damage(), Creature::add_effect(), add_msg(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), spell_effect::bash(), bionic_id, convert_bp(), deal_damage(), Creature::disp_name(), DT_BASH, DT_CUT, effect_downed, fall_damage_mod(), g, has_active_bionic(), hp_to_bp(), string_id< T >::id(), Creature::is_player(), m_bad, m_good, m_warning, num_hp_parts, pos(), rng(), TFLAG_DIGGABLE, TFLAG_SHARP, TFLAG_SWIMMABLE, dealt_damage_instance::total_damage(), and x_in_y().

Referenced by trapfunc::ledge().

◆ in_climate_control()

bool Character::in_climate_control ( )

Returns true if the player is in a climate controlled area or armor.

Definition at line 3816 of file character.cpp.

3817{
3818 bool regulated_area = false;
3819 // Check
3821 return true;
3822 }
3823 map &here = get_map();
3825 in_sleep_state() ) {
3826 return true;
3827 }
3828 for( auto &w : worn ) {
3829 if( w.has_flag( flag_CLIMATE_CONTROL.str() ) ) {
3830 return true;
3831 }
3832 }
3834 // save CPU and simulate acclimation.
3836 if( const optional_vpart_position vp = here.veh_at( pos() ) ) {
3837 // TODO: (?) Force player to scrounge together an AC unit
3838 regulated_area = (
3839 vp->is_inside() && // Already checks for opened doors
3840 vp->vehicle().total_power_w( true ) > 0 // Out of gas? No AC for you!
3841 );
3842 }
3843 // TODO: AC check for when building power is implemented
3844 last_climate_control_ret = regulated_area;
3845 if( !regulated_area ) {
3846 // Takes longer to cool down / warm up with AC, than it does to step outside and feel cruddy.
3847 next_climate_control_check += 40_turns;
3848 }
3849 } else {
3851 }
3852 return regulated_area;
3853}
static const trait_id trait_M_SKIN3("M_SKIN3")
static const flag_str_id flag_CLIMATE_CONTROL("CLIMATE_CONTROL")
static const bionic_id bio_climate("bio_climate")
static const std::string flag_FUNGUS("FUNGUS")
bool has_flag_ter_or_furn(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2322

References bio_climate, flag_CLIMATE_CONTROL, flag_FUNGUS(), get_map(), has_active_bionic(), map::has_flag_ter_or_furn(), has_trait(), in_sleep_state(), last_climate_control_ret, next_climate_control_check, pos(), string_id< T >::str(), trait_M_SKIN3, calendar::turn, map::veh_at(), and worn.

Referenced by update_bodytemp().

◆ in_sleep_state()

◆ in_species()

bool Character::in_species ( const species_id spec) const
overridevirtual

Reimplemented from Creature.

Definition at line 515 of file character.cpp.

516{
517 return spec == HUMAN;
518}
static const species_id HUMAN("HUMAN")

References HUMAN.

◆ initialize_stomach_contents()

void Character::initialize_stomach_contents ( )

Definition at line 195 of file stomach.cpp.

196{
198}

References stomach.

◆ install_bionics()

bool Character::install_bionics ( const itype type,
player installer,
bool  autodoc = false,
int  skill_level = -1 
)

Initialize all the values needed to start the operation player_activity.

Definition at line 2238 of file bionics.cpp.

2240{
2241 if( !type.bionic ) {
2242 debugmsg( "Tried to install NULL bionic" );
2243 return false;
2244 }
2245
2246 const bionic_id &bioid = type.bionic->id;
2247 const bionic_id &upbioid = bioid->upgraded_bionic;
2248 const int difficulty = type.bionic->difficulty;
2249 float adjusted_skill;
2250 int pl_skill;
2251 if( autodoc ) {
2252 adjusted_skill = installer.bionics_adjusted_skill( skill_firstaid,
2255 skill_level );
2256 pl_skill = installer.bionics_pl_skill( skill_firstaid,
2259 skill_level );
2260 } else {
2261 adjusted_skill = installer.bionics_adjusted_skill( skill_electronics,
2264 skill_level );
2265 pl_skill = installer.bionics_pl_skill( skill_electronics,
2268 skill_level );
2269 }
2270 int chance_of_success = bionic_manip_cos( adjusted_skill, difficulty );
2271
2272 // Practice skills only if conducting manual installation
2273 if( !autodoc ) {
2274 installer.practice( skill_electronics, static_cast<int>( ( 100 - chance_of_success ) * 1.5 ) );
2275 installer.practice( skill_firstaid, static_cast<int>( ( 100 - chance_of_success ) * 1.0 ) );
2276 installer.practice( skill_mechanics, static_cast<int>( ( 100 - chance_of_success ) * 0.5 ) );
2277 }
2278
2279 int success = chance_of_success - rng( 0, 99 );
2280 if( installer.has_trait( trait_DEBUG_BIONICS ) ) {
2281 perform_install( bioid, upbioid, difficulty, success, pl_skill, "NOT_MED",
2282 bioid->canceled_mutations );
2283 return true;
2284 }
2285 assign_activity( ACT_OPERATION, to_moves<int>( difficulty * 20_minutes ) );
2286 activity.values.push_back( difficulty );
2287 activity.values.push_back( success );
2288 activity.values.push_back( units::to_joule( bioid->capacity ) );
2289 activity.values.push_back( pl_skill );
2290 activity.str_values.push_back( "install" );
2291 activity.str_values.push_back( bioid.str() );
2292
2293 if( installer.has_trait( trait_PROF_MED ) || installer.has_trait( trait_PROF_AUTODOC ) ) {
2294 activity.str_values.push_back( installer.disp_name( true ) );
2295 } else {
2296 activity.str_values.push_back( "NOT_MED" );
2297 }
2298 if( autodoc ) {
2299 activity.str_values.push_back( "true" );
2300 } else {
2301 activity.str_values.push_back( "false" );
2302 }
2303 for( const std::pair<const bodypart_str_id, int> &elem : bioid->occupied_bodyparts ) {
2304 add_effect( effect_under_op, difficulty * 20_minutes, elem.first->token, difficulty );
2305 }
2306
2307 return true;
2308}
static const activity_id ACT_OPERATION("ACT_OPERATION")
void perform_install(bionic_id bid, bionic_id upbid, int difficulty, int success, int pl_skill, const std::string &installer_name, const std::vector< trait_id > &trait_to_rem)
Success or failure of installation happens here.
Definition: bionics.cpp:2310
void practice(const skill_id &id, int amount, int cap=99, bool suppress_warning=false)
This handles giving xp for a skill.
Definition: character.cpp:3383
std::vector< std::string > str_values
constexpr value_type to_joule(const quantity< value_type, energy_in_joule_tag > &v)
Definition: units_energy.h:40
bionic_id upgraded_bionic
Id of another bionic which this bionic can upgrade.
Definition: bionics.h:127

References ACT_OPERATION, activity, Creature::add_effect(), assign_activity(), iexamine::autodoc(), bionic_manip_cos(), bionics_adjusted_skill(), bionics_pl_skill(), bionic_data::canceled_mutations, bionic_data::capacity, debugmsg, disp_name(), effect_under_op, has_trait(), bionic_data::occupied_bodyparts, perform_install(), practice(), rng(), skill_computer, skill_electronics, skill_firstaid, skill_mechanics, string_id< T >::str(), player_activity::str_values, behavior::success, units::to_joule(), trait_DEBUG_BIONICS, trait_PROF_AUTODOC, trait_PROF_MED, type, bionic_data::upgraded_bionic, and player_activity::values.

Referenced by iexamine::autodoc(), and install_bionic_actor::use().

◆ introduce_into_anesthesia()

void Character::introduce_into_anesthesia ( const time_duration duration,
player installer,
bool  needs_anesthesia 
)

Handles process of introducing patient into anesthesia during Autodoc operations.

Requires anesthesia kits or NOPAIN mutation

Definition at line 2824 of file bionics.cpp.

2826{
2827 if( installer.has_trait( trait_DEBUG_BIONICS ) ) {
2828 installer.add_msg_if_player( m_info,
2829 _( "You tell the pain to bug off and proceed with the operation." ) );
2830 return;
2831 }
2832 installer.add_msg_player_or_npc( m_info,
2833 _( "You set up the operation step-by-step, configuring the Autodoc to manipulate a CBM." ),
2834 _( "<npcname> sets up the operation, configuring the Autodoc to manipulate a CBM." ) );
2835
2837 _( "You settle into position, sliding your right wrist into the couch's strap." ),
2838 _( "<npcname> settles into position, sliding their wrist into the couch's strap." ) );
2839 if( needs_anesthesia ) {
2840 //post-threshold medical mutants do not fear operations.
2843 _( "You feel excited as the operation starts." ) );
2844 }
2845
2847 _( "You feel a tiny pricking sensation in your right arm, and lose all sensation before abruptly blacking out." ) );
2848
2849 //post-threshold medical mutants with Deadened don't need anesthesia due to their inability to feel pain
2850 } else {
2851 //post-threshold medical mutants do not fear operations.
2854 _( "You feel excited as the Autodoc slices painlessly into you. You enjoy the sight of scalpels slicing you apart." ) );
2855 } else {
2857 _( "You stay very, very still, focusing intently on an interesting stain on the ceiling, as the Autodoc slices painlessly into you." ) );
2858 }
2859 }
2860
2861 //Pain junkies feel sorry about missed pain from operation.
2865 _( "As your consciousness slips away, you feel regret that you won't be able to enjoy the operation." ) );
2866 }
2867
2868 if( has_effect( effect_narcosis ) ) {
2869 const time_duration remaining_time = get_effect_dur( effect_narcosis );
2870 if( remaining_time <= duration ) {
2871 const time_duration top_off_time = duration - remaining_time;
2872 add_effect( effect_narcosis, top_off_time );
2873 fall_asleep( top_off_time );
2874 }
2875 } else {
2876 add_effect( effect_narcosis, duration );
2877 fall_asleep( duration );
2878 }
2879}
static const efftype_id effect_narcosis("narcosis")
static const trait_id trait_THRESH_MEDICAL("THRESH_MEDICAL")
static const trait_id trait_MASOCHIST_MED("MASOCHIST_MED")
static const trait_id trait_CENOBITE("CENOBITE")
static const trait_id trait_MASOCHIST("MASOCHIST")
void add_msg_player_or_npc(const std::string &player_msg, const std::string &npc_str) const override
Definition: player.cpp:385
void add_msg_if_player(const std::string &msg) const override
Definition: player.cpp:380

References _, Creature::add_effect(), Creature::add_msg_if_player(), player::add_msg_if_player(), Creature::add_msg_player_or_npc(), player::add_msg_player_or_npc(), effect_narcosis, fall_asleep(), Creature::get_effect_dur(), Creature::has_effect(), has_trait(), m_info, m_mixed, trait_CENOBITE, trait_DEBUG_BIONICS, trait_MASOCHIST, trait_MASOCHIST_MED, and trait_THRESH_MEDICAL.

Referenced by iexamine::autodoc().

◆ inv_dump()

std::vector< item * > Character::inv_dump ( )

Definition at line 8915 of file character.cpp.

8916{
8917 std::vector<item *> ret;
8918 if( is_armed() && can_unwield( weapon ).success() ) {
8919 ret.push_back( &weapon );
8920 }
8921 for( auto &i : worn ) {
8922 ret.push_back( &i );
8923 }
8924 inv.dump( ret );
8925 return ret;
8926}
void dump(std::vector< item * > &dest)
Definition: inventory.cpp:791

References can_unwield(), inventory::dump(), inv, is_armed(), cata::hash64_detail::ret, behavior::success, weapon, and worn.

Referenced by npc::apply_ownership_to_inv(), are_requirements_nearby(), npc::die(), generic_multi_activity_locations(), irradiate(), game::load(), item_action_generator::map_actions_to_items(), place_corpse(), conditional_t< T >::set_has_stolen_item(), sleep(), game::start_game(), and tidy_activity().

◆ invalidate_crafting_inventory()

◆ invlet_to_item()

item * Character::invlet_to_item ( int  invlet)

Return the item pointer of the item with given invlet, return nullptr if the player does not have such an item with that invlet.

Don't use this on npcs. Only use the invlet in the user interface, otherwise always use the item position.

Definition at line 2279 of file character.cpp.

2280{
2281 // Invlets may come from curses, which may also return any kind of key codes, those being
2282 // of type int and they can become valid, but different characters when casted to char.
2283 // Example: KEY_NPAGE (returned when the player presses the page-down key) is 0x152,
2284 // casted to char would yield 0x52, which happens to be 'R', a valid invlet.
2285 if( linvlet > std::numeric_limits<char>::max() || linvlet < std::numeric_limits<char>::min() ) {
2286 return nullptr;
2287 }
2288 const char invlet = static_cast<char>( linvlet );
2289 item *invlet_item = nullptr;
2290 visit_items( [&invlet, &invlet_item]( item * it ) {
2291 if( it->invlet == invlet ) {
2292 invlet_item = it;
2293 return VisitResponse::ABORT;
2294 }
2295 // Visit top-level items only as UIs don't support nested items.
2296 // Also, inventory restack logic depends on this.
2297 return VisitResponse::SKIP;
2298 } );
2299 return invlet_item;
2300}

References item::invlet, SKIP, and visitable< Character >::visit_items().

Referenced by pick_one_up(), game_menus::inv::reassign_letter(), inventory::restack(), show_armor_layers_ui(), and game_menus::inv::swap_letters().

◆ invoke_item() [1/4]

bool Character::invoke_item ( item used)
virtual

As above two, but with position equal to current position.

Reimplemented in avatar, npc, avatar, and npc.

Definition at line 7181 of file character.cpp.

7182{
7183 return invoke_item( used, pos() );
7184}

References invoke_item(), and pos().

◆ invoke_item() [2/4]

bool Character::invoke_item ( item used,
const std::string &  method 
)
virtual

Reimplemented in avatar, npc, avatar, and npc.

Definition at line 7191 of file character.cpp.

7192{
7193 return invoke_item( used, method, pos() );
7194}

References invoke_item(), and pos().

◆ invoke_item() [3/4]

bool Character::invoke_item ( item used,
const std::string &  method,
const tripoint pt 
)
virtual

As above, but with a pre-selected method.

Debugmsg if this item doesn't have this method.

Reimplemented in avatar, npc, and avatar.

Definition at line 7196 of file character.cpp.

7197{
7198 if( !has_enough_charges( *used, true ) ) {
7199 return false;
7200 }
7201
7202 item *actually_used = used->get_usable_item( method );
7203 if( actually_used == nullptr ) {
7204 debugmsg( "Tried to invoke a method %s on item %s, which doesn't have this method",
7205 method.c_str(), used->tname() );
7206 return false;
7207 }
7208
7209 int charges_used = actually_used->type->invoke( *this->as_player(), *actually_used, pt, method );
7210 if( charges_used == 0 ) {
7211 return false;
7212 }
7213 // Prevent accessing the item as it may have been deleted by the invoked iuse function.
7214
7215 if( used->is_tool() || used->is_medication() || used->get_contained().is_medication() ) {
7216 return consume_charges( *actually_used, charges_used );
7217 } else if( used->is_bionic() || used->is_deployable() || method == "place_trap" ) {
7218 i_rem( used );
7219 return true;
7220 }
7221
7222 return false;
7223}
bool has_enough_charges(const item &it, bool show_msg) const
Has the item enough charges to invoke its use function? Also checks if UPS from this player is used i...
Definition: character.cpp:7320
bool consume_charges(item &used, int qty)
Consume charges of a tool or comestible item, potentially destroying it in the process.
Definition: character.cpp:7375
bool is_deployable() const
Definition: item.cpp:6953
item * get_usable_item(const std::string &use_name)
Checks this item and its contents (recursively) for types that have use_function with type use_name.
Definition: item.cpp:7974
bool is_bionic() const
Definition: item.cpp:6557

References Creature::as_player(), consume_charges(), debugmsg, item::get_contained(), item::get_usable_item(), has_enough_charges(), i_rem(), itype::invoke(), item::is_bionic(), item::is_deployable(), item::is_medication(), item::is_tool(), item::tname(), and item::type.

◆ invoke_item() [4/4]

bool Character::invoke_item ( item ,
const tripoint pt 
)
virtual

Asks how to use the item (if it has more than one use_method) and uses it.

Returns true if it destroys the item. Consumes charges from the item. Multi-use items are ONLY supported when all use_methods are iuse_actor!

Reimplemented in avatar, npc, avatar, and npc.

Definition at line 7186 of file character.cpp.

7187{
7188 return false;
7189}

Referenced by activate_bionic(), activate_mutation(), invoke_item(), avatar::invoke_item(), npc::invoke_item(), and iexamine::use_furn_fake_item().

◆ irradiate()

bool Character::irradiate ( float  rads,
bool  bypass = false 
)

Handles mitigation and application of radiation.

Definition at line 1536 of file suffer.cpp.

1537{
1538 int rad_mut = 0;
1539 if( has_trait( trait_RADIOACTIVE3 ) ) {
1540 rad_mut = 3;
1541 } else if( has_trait( trait_RADIOACTIVE2 ) ) {
1542 rad_mut = 2;
1543 } else if( has_trait( trait_RADIOACTIVE1 ) ) {
1544 rad_mut = 1;
1545 }
1546
1547 if( rads > 0 ) {
1548 bool has_helmet = false;
1549 const bool power_armored = is_wearing_power_armor( &has_helmet );
1550 const bool rad_resist = power_armored || worn_with_flag( "RAD_RESIST" );
1551
1552 if( is_rad_immune() && !bypass ) {
1553 // Power armor and some high-tech gear protects completely from radiation
1554 rads = 0.0f;
1555 } else if( rad_resist && !bypass ) {
1556 rads /= 4.0f;
1557 }
1558
1559 if( has_effect( effect_iodine ) ) {
1560 // Radioactive mutation makes iodine less efficient (but more useful)
1561 rads *= 0.3f + 0.1f * rad_mut;
1562 }
1563
1564 int rads_max = roll_remainder( rads );
1565 mod_rad( rng( 0, rads_max ) );
1566
1567 // Apply rads to any radiation badges.
1568 for( item *const it : inv_dump() ) {
1569 if( it->typeId() != itype_rad_badge ) {
1570 continue;
1571 }
1572
1573 // Actual irradiation levels of badges and the player aren't precisely matched.
1574 // This is intentional.
1575 const int before = it->irradiation;
1576
1577 const int delta = rng( 0, rads_max );
1578 if( delta == 0 ) {
1579 continue;
1580 }
1581
1582 it->irradiation += delta;
1583
1584 // If in inventory (not worn), don't print anything.
1585 if( inv.has_item( *it ) ) {
1586 continue;
1587 }
1588
1589 // If the color hasn't changed, don't print anything.
1590 const std::string &col_before = rad_badge_color( before );
1591 const std::string &col_after = rad_badge_color( it->irradiation );
1592 if( col_before == col_after ) {
1593 continue;
1594 }
1595
1596 add_msg_if_player( m_warning, _( "Your radiation badge changes from %1$s to %2$s!" ),
1597 col_before, col_after );
1598 }
1599
1600 if( rads > 0.0f ) {
1601 return true;
1602 }
1603 }
1604 return false;
1605}
std::vector< item * > inv_dump()
Definition: character.cpp:8915
bool is_rad_immune() const
Returns true if the player is protected from radiation.
Definition: character.cpp:6156
std::string rad_badge_color(const int rad)
Definition: item.cpp:289
static const trait_id trait_RADIOACTIVE2("RADIOACTIVE2")
static const trait_id trait_RADIOACTIVE3("RADIOACTIVE3")
static const trait_id trait_RADIOACTIVE1("RADIOACTIVE1")
static const itype_id itype_rad_badge("rad_badge")
static const efftype_id effect_iodine("iodine")

References _, Creature::add_msg_if_player(), effect_iodine, Creature::has_effect(), visitable< T >::has_item(), has_trait(), inv, inv_dump(), is_rad_immune(), is_wearing_power_armor(), itype_rad_badge, m_warning, mod_rad(), rad_badge_color(), rng(), roll_remainder(), trait_RADIOACTIVE1, trait_RADIOACTIVE2, trait_RADIOACTIVE3, and worn_with_flag().

Referenced by trapfunc::glow(), hardcoded_effects(), modify_radiation(), map::player_in_field(), game::process_artifact(), mattack::science(), and suffer_from_radiation().

◆ is_armed()

◆ is_auto_moving()

bool Character::is_auto_moving ( ) const

Definition at line 10461 of file character.cpp.

10462{
10463 return destination_point.has_value();
10464}

References destination_point.

Referenced by game::handle_action(), and avatar_action::move().

◆ is_blind()

bool Character::is_blind ( ) const

◆ is_category_allowed() [1/2]

bool Character::is_category_allowed ( const std::string &  category) const

Definition at line 396 of file mutation.cpp.

397{
398 bool allowed = false;
399 bool restricted = false;
400 for( const trait_id &mut : get_mutations() ) {
401 for( const std::string &Ch_cat : mut.obj().allowed_category ) {
402 restricted = true;
403 if( Ch_cat == category ) {
404 allowed = true;
405 }
406 }
407 }
408 if( !restricted ) {
409 allowed = true;
410 }
411 return allowed;
412}

References get_mutations().

◆ is_category_allowed() [2/2]

bool Character::is_category_allowed ( const std::vector< std::string > &  category) const

Returns true if this category of mutation is allowed.

Definition at line 373 of file mutation.cpp.

374{
375 bool allowed = false;
376 bool restricted = false;
377 for( const trait_id &mut : get_mutations() ) {
378 if( !mut.obj().allowed_category.empty() ) {
379 restricted = true;
380 }
381 for( const std::string &Mu_cat : category ) {
382 if( mut.obj().allowed_category.count( Mu_cat ) ) {
383 allowed = true;
384 break;
385 }
386 }
387
388 }
389 if( !restricted ) {
390 allowed = true;
391 }
392 return allowed;
393
394}

References get_mutations().

Referenced by mutation_ok(), and old_mutate().

◆ is_dead_state()

bool Character::is_dead_state ( ) const
overridevirtual

Returns true if the character should be dead.

Implements Creature.

Definition at line 488 of file character.cpp.

489{
490 return get_part_hp_cur( bodypart_id( "head" ) ) <= 0 ||
491 get_part_hp_cur( bodypart_id( "torso" ) ) <= 0;
492}

References Creature::get_part_hp_cur().

Referenced by apply_damage(), block_hit(), game::do_turn(), game::handle_action(), hurtall(), npc::is_dead(), game::is_game_over(), on_dodge(), vehicle_part::set_crew(), npc::talk_to_u(), game::win(), and game::win_screen().

◆ is_deaf()

◆ is_elec_immune()

bool Character::is_elec_immune ( ) const
overridevirtual

Returns true is the player is protected from electric shocks.

Implements Creature.

Definition at line 6086 of file character.cpp.

6087{
6088 return is_immune_damage( DT_ELECTRIC );
6089}
bool is_immune_damage(damage_type) const override
Returns true if the player is immune to this kind of damage.
Definition: character.cpp:6113

References DT_ELECTRIC, and is_immune_damage().

Referenced by iuse::ehandcuffs(), is_immune_field(), and map::player_in_field().

◆ is_hauling()

bool Character::is_hauling ( ) const

Definition at line 9140 of file character.cpp.

9141{
9142 return hauling;
9143}
bool hauling
Definition: character.h:1537

References hauling.

Referenced by cancel_activity(), haul(), game::place_player(), avatar::set_movement_mode(), game::vertical_move(), and game::walk_move().

◆ is_hibernating()

bool Character::is_hibernating ( ) const

Returns if the player has hibernation mutation and is asleep and well fed.

Definition at line 5139 of file character.cpp.

References effect_sleep, get_kcal_percent(), get_thirst(), has_active_mutation(), Creature::has_effect(), trait_HIBERNATE, and very_thirsty.

Referenced by calc_needs_rates(), and update_needs().

◆ is_immune_damage()

bool Character::is_immune_damage ( damage_type  dt) const
overridevirtual

Returns true if the player is immune to this kind of damage.

Implements Creature.

Definition at line 6113 of file character.cpp.

6114{
6115 switch( dt ) {
6116 case DT_NULL:
6117 return true;
6118 case DT_TRUE:
6119 return false;
6120 case DT_BIOLOGICAL:
6121 return has_effect_with_flag( "EFFECT_BIO_IMMUNE" ) ||
6122 worn_with_flag( "BIO_IMMUNE" );
6123 case DT_BASH:
6124 return has_effect_with_flag( "EFFECT_BASH_IMMUNE" ) ||
6125 worn_with_flag( "BASH_IMMUNE" );
6126 case DT_CUT:
6127 return has_effect_with_flag( "EFFECT_CUT_IMMUNE" ) ||
6128 worn_with_flag( "CUT_IMMUNE" );
6129 case DT_ACID:
6130 return has_trait( trait_ACIDPROOF ) ||
6131 has_effect_with_flag( "EFFECT_ACID_IMMUNE" ) ||
6132 worn_with_flag( "ACID_IMMUNE" );
6133 case DT_STAB:
6134 return has_effect_with_flag( "EFFECT_STAB_IMMUNE" ) ||
6135 worn_with_flag( "STAB_IMMUNE" );
6136 case DT_BULLET:
6137 return has_effect_with_flag( "EFFECT_BULLET_IMMUNE" ) || worn_with_flag( "BULLET_IMMUNE" );
6138 case DT_HEAT:
6139 return has_trait( trait_M_SKIN2 ) ||
6141 has_effect_with_flag( "EFFECT_HEAT_IMMUNE" ) ||
6142 worn_with_flag( "HEAT_IMMUNE" );
6143 case DT_COLD:
6144 return has_effect_with_flag( "EFFECT_COLD_IMMUNE" ) ||
6145 worn_with_flag( "COLD_IMMUNE" );
6146 case DT_ELECTRIC:
6147 return has_active_bionic( bio_faraday ) ||
6148 worn_with_flag( "ELECTRIC_IMMUNE" ) ||
6150 has_effect_with_flag( "EFFECT_ELECTRIC_IMMUNE" );
6151 default:
6152 return true;
6153 }
6154}
static const trait_id trait_ACIDPROOF("ACIDPROOF")
static const trait_id trait_M_SKIN2("M_SKIN2")
static const bionic_id bio_faraday("bio_faraday")
@ AEP_RESIST_ELECTRICITY
Definition: enums.h:117

References AEP_RESIST_ELECTRICITY, bio_faraday, DT_ACID, DT_BASH, DT_BIOLOGICAL, DT_BULLET, DT_COLD, DT_CUT, DT_ELECTRIC, DT_HEAT, DT_NULL, DT_STAB, DT_TRUE, has_active_bionic(), has_artifact_with(), Creature::has_effect_with_flag(), has_trait(), trait_ACIDPROOF, trait_M_SKIN2, trait_M_SKIN3, and worn_with_flag().

Referenced by character_funcs::is_bp_immune_to(), is_elec_immune(), and is_immune_effect().

◆ is_immune_effect()

bool Character::is_immune_effect ( const efftype_id eff) const
overridevirtual

Returns true if the player is immune to this kind of effect.

Implements Creature.

Definition at line 6091 of file character.cpp.

6092{
6093 if( eff == effect_downed ) {
6095 } else if( eff == effect_onfire ) {
6096 return is_immune_damage( DT_HEAT );
6097 } else if( eff == effect_deaf ) {
6099 has_bionic( bio_ears ) ||
6101 } else if( eff == effect_corroding ) {
6103 } else if( eff == effect_nausea ) {
6105 } else if( eff == effect_bleed ) {
6106 // Ugly, it was badly implemented and should be a flag
6107 return mutation_value( "bleed_resist" ) > 0.0f;
6108 }
6109
6110 return false;
6111}
static const trait_id trait_SLIMY("SLIMY")
static const trait_id trait_LEG_TENT_BRACE("LEG_TENT_BRACE")
static const trait_id trait_STRONGSTOMACH("STRONGSTOMACH")
static const itype_id itype_rm13_armor_on("rm13_armor_on")
static const efftype_id effect_corroding("corroding")
static const trait_id trait_VISCOUS("VISCOUS")
static const std::string flag_PARTIAL_DEAF("PARTIAL_DEAF")
static const efftype_id effect_nausea("nausea")
double footwear_factor() const
Returns 1 if the player is wearing something on both feet, .5 if on one, and 0 if on neither.
Definition: character.cpp:8891
bool is_throw_immune() const
Returns true if the player is immune to throws.

References bio_ears, DT_ACID, DT_HEAT, effect_bleed, effect_corroding, effect_deaf, effect_downed, effect_nausea, effect_onfire, flag_DEAF(), flag_PARTIAL_DEAF(), footwear_factor(), has_bionic(), has_trait(), is_immune_damage(), is_throw_immune(), is_wearing(), itype_rm13_armor_on, mutation_value(), trait_LEG_TENT_BRACE, trait_SLIMY, trait_STRONGSTOMACH, trait_VISCOUS, and worn_with_flag().

Referenced by sounds::process_sound_markers().

◆ is_immune_field()

bool Character::is_immune_field ( const field_type_id ) const
overridevirtual

Returns true if we are immune to the field type with the given fid.

Does not handle intensity, so this function should only be called through is_dangerous_field().

Reimplemented from Creature.

Definition at line 6045 of file character.cpp.

6046{
6047 // Obviously this makes us invincible
6048 if( has_trait( trait_DEBUG_NODMG ) ) {
6049 return true;
6050 }
6051 // Check to see if we are immune
6052 const field_type &ft = fid.obj();
6053 for( const trait_id &t : ft.immunity_data_traits ) {
6054 if( has_trait( t ) ) {
6055 return true;
6056 }
6057 }
6058 bool immune_by_body_part_resistance = !ft.immunity_data_body_part_env_resistance.empty();
6059 for( const std::pair<body_part, int> &fide : ft.immunity_data_body_part_env_resistance ) {
6060 immune_by_body_part_resistance = immune_by_body_part_resistance &&
6061 get_env_resist( convert_bp( fide.first ).id() ) >= fide.second;
6062 }
6063 if( immune_by_body_part_resistance ) {
6064 return true;
6065 }
6066 if( ft.has_elec ) {
6067 return is_elec_immune();
6068 }
6069 if( ft.has_fire ) {
6071 }
6072 if( ft.has_acid ) {
6073 return !is_on_ground() && get_env_resist( bodypart_id( "foot_l" ) ) >= 15 &&
6074 get_env_resist( bodypart_id( "foot_r" ) ) >= 15 &&
6075 get_env_resist( bodypart_id( "leg_l" ) ) >= 15 &&
6076 get_env_resist( bodypart_id( "leg_r" ) ) >= 15 &&
6077 get_armor_type( DT_ACID, bodypart_id( "foot_l" ) ) >= 5 &&
6078 get_armor_type( DT_ACID, bodypart_id( "foot_r" ) ) >= 5 &&
6079 get_armor_type( DT_ACID, bodypart_id( "leg_l" ) ) >= 5 &&
6080 get_armor_type( DT_ACID, bodypart_id( "leg_r" ) ) >= 5;
6081 }
6082 // If we haven't found immunity yet fall up to the next level
6083 return Creature::is_immune_field( fid );
6084}
static const bionic_id bio_heatsink("bio_heatsink")
bool is_elec_immune() const override
Returns true is the player is protected from electric shocks.
Definition: character.cpp:6086
bool is_on_ground() const override
Returns true if the player is knocked over or has broken legs.
Definition: character.cpp:883
int get_env_resist(bodypart_id bp) const override
Returns overall env_resist on a body_part.
Definition: character.cpp:6987
virtual bool is_immune_field(const field_type_id &) const
Returns true if we are immune to the field type with the given fid.
Definition: creature.h:327
std::vector< trait_id > immunity_data_traits
Definition: field_type.h:172
bool has_elec
Definition: field_type.h:164
bool has_acid
Definition: field_type.h:163
bool has_fire
Definition: field_type.h:162
std::vector< std::pair< body_part, int > > immunity_data_body_part_env_resistance
Definition: field_type.h:173

References bio_heatsink, convert_bp(), DT_ACID, get_armor_type(), get_env_resist(), field_type::has_acid, has_active_bionic(), field_type::has_elec, field_type::has_fire, has_trait(), string_id< T >::id(), field_type::immunity_data_body_part_env_resistance, field_type::immunity_data_traits, is_elec_immune(), Creature::is_immune_field(), is_on_ground(), is_wearing(), itype_rm13_armor_on, int_id< T >::obj(), and trait_DEBUG_NODMG.

◆ is_invisible()

bool Character::is_invisible ( ) const

Definition at line 6244 of file character.cpp.

6245{
6246 return (
6251 );
6252}
static const std::string flag_EFFECT_INVISIBLE("EFFECT_INVISIBLE")

References AEP_INVISIBLE, flag_EFFECT_INVISIBLE(), has_artifact_with(), Creature::has_effect_with_flag(), has_trait(), is_wearing_active_optcloak(), and trait_DEBUG_CLOAK.

Referenced by visibility().

◆ is_limb_broken()

bool Character::is_limb_broken ( const bodypart_id limb) const

◆ is_limb_disabled()

bool Character::is_limb_disabled ( const bodypart_id limb) const

Returns true if the limb is disabled(12.5% or less hp)

Definition at line 1238 of file character.cpp.

1239{
1240 return get_part_hp_cur( limb ) <= get_part_hp_max( limb ) * .125;
1241}

References Creature::get_part_hp_cur(), and Creature::get_part_hp_max().

Referenced by best_shield(), and get_working_arm_count().

◆ is_limb_hindered()

bool Character::is_limb_hindered ( hp_part  limb) const

Returns true if the limb is hindered(40% or less hp)

◆ is_max_power()

bool Character::is_max_power ( ) const

Definition at line 1922 of file character.cpp.

1923{
1924 return power_level >= max_power_level;
1925}

References max_power_level, and power_level.

Referenced by feed_furnace_with().

◆ is_mounted()

bool Character::is_mounted ( ) const

Definition at line 1064 of file character.cpp.

1065{
1067}

References effect_riding, Creature::has_effect(), and mounted_creature.

Referenced by activate_bionic(), cata_event_dispatch::avatar_moves(), best_nearby_lifting_assist(), iuse::blood_draw(), iuse::boltcutters(), iuse::burrow(), can_install_bionics(), map::can_move_furniture(), cauterize_actor::can_use(), enzlave_actor::can_use(), musical_instrument_actor::can_use(), install_bionic_actor::can_use(), repair_item_actor::can_use_tool(), can_wield(), iuse::capture_monster_act(), iuse::capture_monster_veh(), debug_menu::character_edit_menu(), check_mount_is_spooked(), check_mount_will_move(), iuse::chop_logs(), iuse::chop_tree(), iuse::clear_rubble(), iuse::craft(), iuse::crowbar(), iuse::cut_log_into_planks(), npc::die(), iuse::dig(), iuse::dig_channel(), iuse::disassemble(), dismount(), game::do_turn(), iuse::einktabletpc(), game::examine(), iuse::fill_pit(), ranged::fire_gun(), iuse::fish_trap(), iuse::fishing_rod(), iuse::gun_repair(), ranged::gunmode_checks_weapon(), iuse::hacksaw(), iuse::hairkit(), iuse::hammer(), game::handle_action(), has_charges(), iuse::jackhammer(), iuse::ladder(), character_funcs::list_ammo(), iuse::lumber(), iuse::makemound(), iuse::meditate(), melee_attack(), iuse::mind_splicer(), mine_activity(), iuse::mop(), avatar_action::move(), npc::move_to(), game::npc_menu(), game::on_move_effects(), overmap_sight_range(), iuse::oxytorch(), perform_technique(), iuse::pickaxe(), npc::place_on_map(), game::place_player(), game::place_player_overmap(), avatar_action::plthrow(), iuse::portable_game(), iuse::portal(), game::prompt_dangerous_tile(), recalc_sight_limits(), reset_stats(), iuse::rpgdie(), run_cost(), avatar::set_movement_mode(), iuse::shavekit(), iuse::siphon(), sleep(), smash(), store(), avatar_action::swim(), swim_speed(), iuse::teleport(), ranged::throw_item(), throw_range(), trapfunc::tripwire(), iuse::unfold_generic(), unfold_vehicle_iuse::use(), pick_lock_actor::use(), deploy_furn_actor::use(), cauterize_actor::use(), enzlave_actor::use(), musical_instrument_actor::use(), heal_actor::use(), place_trap_actor::use(), deploy_tent_actor::use(), sew_advanced_actor::use(), weigh_self_actor::use(), use_charges(), game::vertical_move(), iuse::vibe(), game::walk_move(), iuse::wash_hard_items(), wash_items(), iuse::wash_soft_items(), iuse::water_purifier(), weight_capacity(), and npc::worker_downtime().

◆ is_on_ground()

bool Character::is_on_ground ( ) const
overridevirtual

Returns true if the player is knocked over or has broken legs.

Implements Creature.

Definition at line 883 of file character.cpp.

884{
886}

References effect_downed, get_working_leg_count(), and Creature::has_effect().

Referenced by is_immune_field(), map::player_in_field(), and game::walk_move().

◆ is_quiet()

bool Character::is_quiet ( ) const

Returns true if the player has quiet melee attacks.

Definition at line 1177 of file martialarts.cpp.

1178{
1179 return search_ma_buff_effect( *effects, []( const ma_buff & b, const effect & ) {
1180 return b.is_quiet();
1181 } );
1182}

References b, Creature::effects, and search_ma_buff_effect().

Referenced by melee_attack().

◆ is_rad_immune()

bool Character::is_rad_immune ( ) const

Returns true if the player is protected from radiation.

Definition at line 6156 of file character.cpp.

6157{
6158 bool has_helmet = false;
6159 return ( is_wearing_power_armor( &has_helmet ) && has_helmet ) || worn_with_flag( "RAD_PROOF" );
6160}

References is_wearing_power_armor(), and worn_with_flag().

Referenced by irradiate(), and suffer_from_radiation().

◆ is_snuggling()

std::string Character::is_snuggling ( ) const

Checks to see if the player is using floor items to keep warm, and return the name of one such item if so.

Definition at line 9281 of file character.cpp.

9282{
9283 map &here = get_map();
9284 auto begin = here.i_at( pos() ).begin();
9285 auto end = here.i_at( pos() ).end();
9286
9287 if( in_vehicle ) {
9288 if( const cata::optional<vpart_reference> vp = here.veh_at( pos() ).part_with_feature( VPFLAG_CARGO,
9289 false ) ) {
9290 vehicle *const veh = &vp->vehicle();
9291 const int cargo = vp->part_index();
9292 if( !veh->get_items( cargo ).empty() ) {
9293 begin = veh->get_items( cargo ).begin();
9294 end = veh->get_items( cargo ).end();
9295 }
9296 }
9297 }
9298 const item *floor_armor = nullptr;
9299 int ticker = 0;
9300
9301 // If there are no items on the floor, return nothing
9302 if( begin == end ) {
9303 return "nothing";
9304 }
9305
9306 for( auto candidate = begin; candidate != end; ++candidate ) {
9307 if( !candidate->is_armor() ) {
9308 continue;
9309 } else if( candidate->volume() > 250_ml && candidate->get_warmth() > 0 &&
9310 ( candidate->covers( bp_torso ) || candidate->covers( bp_leg_l ) ||
9311 candidate->covers( bp_leg_r ) ) ) {
9312 floor_armor = &*candidate;
9313 ticker++;
9314 }
9315 }
9316
9317 if( ticker == 0 ) {
9318 return "nothing";
9319 } else if( ticker == 1 ) {
9320 return floor_armor->type_name();
9321 } else if( ticker > 1 ) {
9322 return "many";
9323 }
9324
9325 return "nothing";
9326}
bool in_vehicle
Definition: character.h:1536
bool empty() const
Definition: item_stack.cpp:15

References item_stack::begin(), bp_leg_l, bp_leg_r, bp_torso, item_stack::empty(), item_stack::end(), vehicle::get_items(), get_map(), map::i_at(), in_vehicle, pos(), item::type_name(), map::veh_at(), vehicle::vehicle(), and VPFLAG_CARGO.

Referenced by fall_asleep().

◆ is_stealthy()

bool Character::is_stealthy ( ) const

Returns true if the player has stealthy movement.

Definition at line 1183 of file martialarts.cpp.

1184{
1185 return search_ma_buff_effect( *effects, []( const ma_buff & b, const effect & ) {
1186 return b.is_stealthy();
1187 } );
1188}

References b, Creature::effects, and search_ma_buff_effect().

Referenced by game::walk_move().

◆ is_throw_immune()

bool Character::is_throw_immune ( ) const

Returns true if the player is immune to throws.

Definition at line 1171 of file martialarts.cpp.

1172{
1173 return search_ma_buff_effect( *effects, []( const ma_buff & b, const effect & ) {
1174 return b.is_throw_immune();
1175 } );
1176}

References b, Creature::effects, and search_ma_buff_effect().

Referenced by mattack::bio_op_takedown(), mattack::grab(), is_immune_effect(), mattack::thrown_by_judo(), and game::update_stair_monsters().

◆ is_visible_in_range()

bool Character::is_visible_in_range ( const Creature critter,
int  range 
) const
private

Check whether the other creature is in range and can be seen by this creature.

Parameters
critterCreature to check for visibility
rangeThe maximal distance (rl_dist), creatures at this distance or less are included.

Definition at line 10178 of file character.cpp.

10179{
10180 return sees( critter ) && rl_dist( pos(), critter.pos() ) <= range;
10181}

References Creature::pos(), pos(), rl_dist(), and sees().

◆ is_warm()

bool Character::is_warm ( ) const
overridevirtual

Reimplemented from Creature.

Definition at line 520 of file character.cpp.

521{
522 // TODO: is there a mutation (plant?) that makes a npc not warm blooded?
523 return true;
524}

◆ is_waterproof()

bool Character::is_waterproof ( const body_part_set parts) const

Definition at line 8951 of file character.cpp.

8952{
8953 return covered_with_flag( "WATERPROOF", parts );
8954}
bool covered_with_flag(const std::string &flag, const body_part_set &parts) const
Definition: character.cpp:8928

References covered_with_flag().

Referenced by drench().

◆ is_weak_to_water()

bool Character::is_weak_to_water ( ) const

Definition at line 414 of file mutation.cpp.

415{
416 for( const trait_id &mut : get_mutations() ) {
417 if( mut.obj().weakness_to_water > 0 ) {
418 return true;
419 }
420 }
421 return false;
422}

References get_mutations().

Referenced by drench().

◆ is_wearing() [1/2]

◆ is_wearing() [2/2]

bool Character::is_wearing ( const itype_id it) const

Returns true if the player is wearing an item of this type.

Definition at line 3211 of file character.cpp.

3212{
3213 for( auto &i : worn ) {
3214 if( i.typeId() == it ) {
3215 return true;
3216 }
3217 }
3218 return false;
3219}

References worn.

◆ is_wearing_active_optcloak()

bool Character::is_wearing_active_optcloak ( ) const

Returns true if the player is wearing an active optical cloak.

Definition at line 3806 of file character.cpp.

3807{
3808 for( auto &w : worn ) {
3809 if( w.active && w.has_flag( flag_ACTIVE_CLOAKING ) ) {
3810 return true;
3811 }
3812 }
3813 return false;
3814}
static const std::string flag_ACTIVE_CLOAKING("ACTIVE_CLOAKING")

References flag_ACTIVE_CLOAKING(), and worn.

Referenced by basic_symbol_color(), and is_invisible().

◆ is_wearing_active_power_armor()

bool Character::is_wearing_active_power_armor ( ) const

Returns true if the character is wearing active power.

Definition at line 3796 of file character.cpp.

3797{
3798 for( const auto &w : worn ) {
3799 if( w.has_flag( flag_POWERARMOR_EXO ) && w.active ) {
3800 return true;
3801 }
3802 }
3803 return false;
3804}

References flag_POWERARMOR_EXO(), and worn.

◆ is_wearing_helmet()

bool Character::is_wearing_helmet ( ) const

Returns true if the character is wearing something occupying the helmet slot.

Definition at line 8854 of file character.cpp.

8855{
8856 for( const item &i : worn ) {
8857 if( i.covers( bp_head ) && !i.has_flag( flag_HELMET_COMPAT ) && !i.has_flag( flag_SKINTIGHT ) &&
8858 !i.has_flag( flag_PERSONAL ) && !i.has_flag( flag_AURA ) && !i.has_flag( flag_SEMITANGIBLE ) &&
8859 !i.has_flag( flag_OVERSIZE ) ) {
8860 return true;
8861 }
8862 }
8863 return false;
8864}

References bp_head, flag_AURA(), flag_HELMET_COMPAT(), flag_OVERSIZE(), flag_PERSONAL(), flag_SEMITANGIBLE(), flag_SKINTIGHT(), and worn.

Referenced by can_wear().

◆ is_wearing_on_bp()

bool Character::is_wearing_on_bp ( const itype_id it,
const bodypart_id bp 
) const

Returns true if the player is wearing the item on the given body part.

Definition at line 3221 of file character.cpp.

3222{
3223 for( auto &i : worn ) {
3224 if( i.typeId() == it && i.covers( bp->token ) ) {
3225 return true;
3226 }
3227 }
3228 return false;
3229}

References worn.

Referenced by shoe_type_count().

◆ is_wearing_power_armor()

bool Character::is_wearing_power_armor ( bool *  hasHelmet = nullptr) const

Returns true if the character is wearing power armor.

Definition at line 3771 of file character.cpp.

3772{
3773 bool result = false;
3774 for( auto &elem : worn ) {
3775 if( !elem.is_power_armor() ) {
3776 continue;
3777 }
3778 if( elem.has_flag( flag_POWERARMOR_EXO ) ) {
3779 result = true;
3780 if( hasHelmet == nullptr ) {
3781 // found power armor, helmet not requested, cancel loop
3782 return true;
3783 }
3784 }
3785 // found power armor, continue search for helmet
3786 if( elem.covers( bp_head ) ) {
3787 if( hasHelmet != nullptr ) {
3788 *hasHelmet = true;
3789 }
3790 return true;
3791 }
3792 }
3793 return result;
3794}

References bp_head, flag_POWERARMOR_EXO(), and worn.

Referenced by can_wear(), irradiate(), is_rad_immune(), power_rating(), and suffer_from_radiation().

◆ is_wearing_shoes()

bool Character::is_wearing_shoes ( const side which_side = side::BOTH) const

Returns true if the player is wearing something on their feet that is not SKINTIGHT.

Definition at line 8825 of file character.cpp.

8826{
8827 bool left = true;
8828 bool right = true;
8829 if( which_side == side::LEFT || which_side == side::BOTH ) {
8830 left = false;
8831 for( const item &worn_item : worn ) {
8832 if( worn_item.covers( bp_foot_l ) && !worn_item.has_flag( flag_BELTED ) &&
8833 !worn_item.has_flag( flag_PERSONAL ) && !worn_item.has_flag( flag_AURA ) &&
8834 !worn_item.has_flag( flag_SEMITANGIBLE ) && !worn_item.has_flag( flag_SKINTIGHT ) ) {
8835 left = true;
8836 break;
8837 }
8838 }
8839 }
8840 if( which_side == side::RIGHT || which_side == side::BOTH ) {
8841 right = false;
8842 for( const item &worn_item : worn ) {
8843 if( worn_item.covers( bp_foot_r ) && !worn_item.has_flag( flag_BELTED ) &&
8844 !worn_item.has_flag( flag_PERSONAL ) && !worn_item.has_flag( flag_AURA ) &&
8845 !worn_item.has_flag( flag_SEMITANGIBLE ) && !worn_item.has_flag( flag_SKINTIGHT ) ) {
8846 right = true;
8847 break;
8848 }
8849 }
8850 }
8851 return ( left && right );
8852}

References BOTH, bp_foot_l, bp_foot_r, flag_AURA(), flag_BELTED(), flag_PERSONAL(), flag_SEMITANGIBLE(), flag_SKINTIGHT(), LEFT, left, RIGHT, right, and worn.

Referenced by can_wear(), rooted_message(), and suffer_from_other_mutations().

◆ is_wielding()

◆ is_worn()

◆ item_encumb()

void Character::item_encumb ( char_encumbrance_data vals,
const item new_item 
) const
protected

Applies encumbrance from items only If new_item is not null, then calculate under the asumption that it is added to existing work items.

Definition at line 3946 of file character.cpp.

3947{
3948
3949 // reset all layer data
3950 vals = char_encumbrance_data();
3951
3952 // Figure out where new_item would be worn
3953 std::list<item>::const_iterator new_item_position = worn.end();
3954 if( !new_item.is_null() ) {
3955 // const_cast required to work around g++-4.8 library bug
3956 // see the commit that added this comment to understand why
3957 new_item_position =
3958 const_cast<Character *>( this )->position_to_wear_new_item( new_item );
3959 }
3960
3961 // Track highest layer observed so far so we can penalize out-of-order
3962 // items
3963 std::array<layer_level, num_bp> highest_layer_so_far;
3964 std::fill( highest_layer_so_far.begin(), highest_layer_so_far.end(),
3966
3967 for( auto w_it = worn.begin(); w_it != worn.end(); ++w_it ) {
3968 if( w_it == new_item_position ) {
3969 layer_item( vals, new_item, highest_layer_so_far, *this );
3970 }
3971 layer_item( vals, *w_it, highest_layer_so_far, *this );
3972 }
3973
3974 if( worn.end() == new_item_position && !new_item.is_null() ) {
3975 layer_item( vals, new_item, highest_layer_so_far, *this );
3976 }
3977
3978 // make sure values are sane
3979 for( const body_part bp : all_body_parts ) {
3980 encumbrance_data &elem = vals.elems[bp];
3981
3982 elem.armor_encumbrance = std::max( 0, elem.armor_encumbrance );
3983
3984 // Add armor and layering penalties for the final values
3985 elem.encumbrance += elem.armor_encumbrance + elem.layer_penalty;
3986 }
3987}
static void layer_item(char_encumbrance_data &vals, const item &it, std::array< layer_level, num_bp > &highest_layer_so_far, const Character &c)
Definition: character.cpp:3729
std::list< item >::iterator position_to_wear_new_item(const item &new_item)
Return the position in the worn list where new_item would be put by default.
Definition: character.cpp:3917
@ PERSONAL_LAYER
Definition: enums.h:216
FMT_NOINLINE OutputIt fill(OutputIt it, size_t n, const fill_t< Char > &fill)
std::array< encumbrance_data, num_bp > elems

References all_body_parts, encumbrance_data::armor_encumbrance, char_encumbrance_data::elems, encumbrance_data::encumbrance, detail::fill(), item::is_null(), layer_item(), encumbrance_data::layer_penalty, PERSONAL_LAYER, position_to_wear_new_item(), and worn.

Referenced by calc_encumbrance().

◆ item_handling_cost()

int Character::item_handling_cost ( const item it,
bool  penalties = true,
int  base_cost = INVENTORY_HANDLING_PENALTY 
) const

Calculate (but do not deduct) the number of moves required when handling (e.g.

storing, drawing etc.) an item

Parameters
itItem to calculate handling cost for
penaltiesWhether item volume and temporary effects (e.g. GRABBED, DOWNED) should be considered.
base_costCost due to storage type.
Returns
cost in moves ranging from 0 to MAX_HANDLING_COST

Definition at line 7432 of file character.cpp.

7433{
7434 int mv = base_cost;
7435 if( penalties ) {
7436 // 40 moves per liter, up to 200 at 5 liters
7437 mv += std::min( 200, it.volume() / 20_ml );
7438 }
7439
7440 if( weapon.typeId() == itype_e_handcuffs ) {
7441 mv *= 4;
7442 } else if( penalties && has_effect( effect_grabbed ) ) {
7443 mv *= 2;
7444 }
7445
7446 // For single handed items use the least encumbered hand
7447 if( it.is_two_handed( *this ) ) {
7448 mv += encumb( bp_hand_l ) + encumb( bp_hand_r );
7449 } else {
7450 mv += std::min( encumb( bp_hand_l ), encumb( bp_hand_r ) );
7451 }
7452
7453 return std::min( std::max( mv, 0 ), MAX_HANDLING_COST );
7454}
static const itype_id itype_e_handcuffs("e_handcuffs")
static constexpr int MAX_HANDLING_COST

References bp_hand_l, bp_hand_r, effect_grabbed, encumb(), Creature::has_effect(), item::is_two_handed(), itype_e_handcuffs, MAX_HANDLING_COST, item::typeId(), item::volume(), and weapon.

Referenced by dispose_item(), npc::dispose_item(), throw_activity_actor::do_turn(), item_reload_cost(), item_store_cost(), item_wear_cost(), mill_activate(), mill_load_food(), iexamine::quern_examine(), smoker_activate(), smoker_load_food(), iexamine::smoker_options(), character_funcs::try_wield_contents(), avatar_funcs::unload_item(), and avatar::wield().

◆ item_reload_cost()

int Character::item_reload_cost ( const item it,
const item ammo,
int  qty 
) const

Calculate (but do not deduct) the number of moves required to reload an item with specified quantity of ammo.

Parameters
itItem to calculate reload cost for
ammoeither ammo or magazine to use when reloading the item
qtymaximum units of ammo to reload. Capped by remaining capacity and ignored if reloading using a magazine.
Gun decreases the time taken to reload a magazine Pistol decreases time taken to reload a pistol Smg decreases time taken to reload an SMG Rifle decreases time taken to reload a rifle Shotgun decreases time taken to reload a shotgun Launcher decreases time taken to reload a launcher Strength reduces reload time of some weapons

Definition at line 10896 of file character.cpp.

10897{
10898 if( ammo.is_ammo() ) {
10899 qty = std::max( std::min( ammo.charges, qty ), 1 );
10900 } else if( ammo.is_ammo_container() || ammo.is_container() ) {
10901 qty = clamp( qty, ammo.contents.front().charges, 1 );
10902 } else if( ammo.is_magazine() ) {
10903 qty = 1;
10904 } else {
10905 debugmsg( "cannot determine reload cost as %s is neither ammo or magazine", ammo.tname() );
10906 return 0;
10907 }
10908
10909 // If necessary create duplicate with appropriate number of charges
10910 item obj = ammo;
10911 obj = obj.split( qty );
10912 if( obj.is_null() ) {
10913 obj = ammo;
10914 }
10915 // No base cost for handling ammo - that's already included in obtain cost
10916 // We have the ammo in our hands right now
10917 int mv = item_handling_cost( obj, true, 0 );
10918
10919 if( ammo.has_flag( "MAG_BULKY" ) ) {
10920 mv *= 1.5; // bulky magazines take longer to insert
10921 }
10922
10923 if( !it.is_gun() && !it.is_magazine() ) {
10924 return mv + 100; // reload a tool or sealable container
10925 }
10926
10927 /** @EFFECT_GUN decreases the time taken to reload a magazine */
10928 /** @EFFECT_PISTOL decreases time taken to reload a pistol */
10929 /** @EFFECT_SMG decreases time taken to reload an SMG */
10930 /** @EFFECT_RIFLE decreases time taken to reload a rifle */
10931 /** @EFFECT_SHOTGUN decreases time taken to reload a shotgun */
10932 /** @EFFECT_LAUNCHER decreases time taken to reload a launcher */
10933
10934 int cost = ( it.is_gun() ? it.get_reload_time() : it.type->magazine->reload_time ) * qty;
10935
10936 skill_id sk = it.is_gun() ? it.type->gun->skill_used : skill_gun;
10937 mv += cost / ( 1.0f + std::min( get_skill_level( sk ) * 0.1f, 1.0f ) );
10938
10939 if( it.has_flag( "STR_RELOAD" ) ) {
10940 /** @EFFECT_STR reduces reload time of some weapons */
10941 mv -= get_str() * 20;
10942 }
10943
10944 return std::max( mv, 25 );
10945}
static const skill_id skill_gun("gun")
item split(int qty)
Splits a count-by-charges item always leaving source item with minimum of 1 charge.
Definition: item.cpp:721
int get_reload_time() const
Returns the reload time of the gun.
Definition: item.cpp:6533
bool is_magazine() const
Definition: item.cpp:6562
cata::value_ptr< islot_gun > gun
Definition: itype.h:859

References item::charges, clamp(), item::contents, debugmsg, item_contents::front(), item::get_reload_time(), get_skill_level(), get_str(), itype::gun, item::has_flag(), item::is_ammo(), item::is_ammo_container(), item::is_container(), item::is_gun(), item::is_magazine(), item::is_null(), item_handling_cost(), itype::magazine, skill_gun, item::split(), item::tname(), and item::type.

Referenced by npc::do_reload(), npc::enough_time_to_reload(), item_reload_option::moves(), and avatar_funcs::unload_item().

◆ item_store_cost()

int Character::item_store_cost ( const item it,
const item container,
bool  penalties = true,
int  base_cost = INVENTORY_HANDLING_PENALTY 
) const

Calculate (but do not deduct) the number of moves required when storing an item in a container.

Parameters
itItem to calculate storage cost for
containerContainer to store item in
penaltiesWhether item volume and temporary effects (e.g. GRABBED, DOWNED) should be considered.
base_costCost due to storage type.
Returns
cost in moves ranging from 0 to MAX_HANDLING_COST
Pistol decreases time taken to store a pistol Smg decreases time taken to store an SMG Rifle decreases time taken to store a rifle Shotgun decreases time taken to store a shotgun Launcher decreases time taken to store a launcher Stabbing decreases time taken to store a stabbing weapon Cutting decreases time taken to store a cutting weapon Bashing decreases time taken to store a bashing weapon

Definition at line 7456 of file character.cpp.

7458{
7459 /** @EFFECT_PISTOL decreases time taken to store a pistol */
7460 /** @EFFECT_SMG decreases time taken to store an SMG */
7461 /** @EFFECT_RIFLE decreases time taken to store a rifle */
7462 /** @EFFECT_SHOTGUN decreases time taken to store a shotgun */
7463 /** @EFFECT_LAUNCHER decreases time taken to store a launcher */
7464 /** @EFFECT_STABBING decreases time taken to store a stabbing weapon */
7465 /** @EFFECT_CUTTING decreases time taken to store a cutting weapon */
7466 /** @EFFECT_BASHING decreases time taken to store a bashing weapon */
7467 int lvl = get_skill_level( it.is_gun() ? it.gun_skill() : it.melee_skill() );
7468 return item_handling_cost( it, penalties, base_cost ) / ( ( lvl + 10.0f ) / 10.0f );
7469}
skill_id gun_skill() const
The skill used to operate the gun.
Definition: item.cpp:7187

References get_skill_level(), item::gun_skill(), item::is_gun(), item_handling_cost(), and item::melee_skill().

Referenced by dispose_item(), npc::dispose_item(), and character_funcs::store_in_container().

◆ item_wear_cost()

int Character::item_wear_cost ( const item it) const

Calculate (but do not deduct) the number of moves required to wear an item.

Definition at line 7471 of file character.cpp.

7472{
7473 double mv = item_handling_cost( it );
7474
7475 switch( it.get_layer() ) {
7476 case PERSONAL_LAYER:
7477 break;
7478
7479 case UNDERWEAR_LAYER:
7480 mv *= 1.5;
7481 break;
7482
7483 case REGULAR_LAYER:
7484 break;
7485
7486 case WAIST_LAYER:
7487 case OUTER_LAYER:
7488 mv /= 1.5;
7489 break;
7490
7491 case BELTED_LAYER:
7492 mv /= 2.0;
7493 break;
7494
7495 case AURA_LAYER:
7496 break;
7497
7498 default:
7499 break;
7500 }
7501
7502 mv *= std::max( it.get_encumber( *this ) / 10.0, 1.0 );
7503
7504 return mv;
7505}
layer_level get_layer() const
Returns clothing layer for item.
Definition: item.cpp:5880
@ WAIST_LAYER
Definition: enums.h:222
@ UNDERWEAR_LAYER
Definition: enums.h:218
@ REGULAR_LAYER
Definition: enums.h:220
@ BELTED_LAYER
Definition: enums.h:226
@ AURA_LAYER
Definition: enums.h:228
@ OUTER_LAYER
Definition: enums.h:224

References AURA_LAYER, BELTED_LAYER, item::get_encumber(), item::get_layer(), item_handling_cost(), OUTER_LAYER, PERSONAL_LAYER, REGULAR_LAYER, UNDERWEAR_LAYER, and WAIST_LAYER.

Referenced by dispose_item(), and wear_item().

◆ item_with_best_of_quality()

item & Character::item_with_best_of_quality ( const quality_id qid)

Returns the item in the player's inventory with the highest of the specified quality.

Definition at line 9962 of file character.cpp.

9963{
9964 int maxq = max_quality( qid );
9965 auto items_with_quality = items_with( [qid]( const item & it ) {
9966 return it.has_quality( qid );
9967 } );
9968 for( item *it : items_with_quality ) {
9969 if( it->get_quality( qid ) == maxq ) {
9970 return *it;
9971 }
9972 }
9973 return null_item_reference();
9974}
int get_quality(const quality_id &id) const
Definition: item.cpp:5388

References item::get_quality(), visitable< T >::has_quality(), visitable< Character >::items_with(), visitable< Character >::max_quality(), and null_item_reference().

◆ item_worn_with_flag()

const item * Character::item_worn_with_flag ( const std::string &  flag,
const bodypart_id bp = bodypart_str_id::NULL_ID() 
) const

Returns the first worn item with a given flag.

Definition at line 3239 of file character.cpp.

3240{
3241 const item *it_with_flag = nullptr;
3242 for( const item &it : worn ) {
3243 if( it.has_flag( flag ) && ( bp == bodypart_str_id::NULL_ID() ||
3244 it.covers( bp->token ) ) ) {
3245 it_with_flag = &it;
3246 break;
3247 }
3248 }
3249 return it_with_flag;
3250}

References string_id< body_part_type >::NULL_ID(), and worn.

Referenced by burn_fuel().

◆ knock_back_to()

void Character::knock_back_to ( const tripoint to)
overridevirtual

Knocks the character to a specified tile.

Maximum Strength allows knocked back player to knock back, damage, stun some monsters

Implements Creature.

Definition at line 10787 of file character.cpp.

10788{
10789 if( to == pos() ) {
10790 return;
10791 }
10792
10793 if( rl_dist( pos(), to ) < 2 && get_map().obstructed_by_vehicle_rotation( pos(), to ) ) {
10794 tripoint intervening = to;
10795 if( one_in( 2 ) ) {
10796 intervening.x = pos().x;
10797 } else {
10798 intervening.y = pos().y;
10799 }
10800
10801 apply_damage( nullptr, bodypart_id( "torso" ), 3 );
10802 add_effect( effect_stunned, 2_turns );
10803 add_msg_player_or_npc( _( "You bounce off a %s!" ), _( "<npcname> bounces off a %s!" ),
10804 g->m.obstacle_name( intervening ) );
10805 return;
10806 }
10807
10808 // First, see if we hit a monster
10809 if( monster *const critter = g->critter_at<monster>( to ) ) {
10810 deal_damage( critter, bodypart_id( "torso" ), damage_instance( DT_BASH, critter->type->size ) );
10811 add_effect( effect_stunned, 1_turns );
10812 /** @EFFECT_STR_MAX allows knocked back player to knock back, damage, stun some monsters */
10813 if( ( str_max - 6 ) / 4 > critter->type->size ) {
10814 critter->knock_back_from( pos() ); // Chain reaction!
10815 critter->apply_damage( this, bodypart_id( "torso" ), ( str_max - 6 ) / 4 );
10816 critter->add_effect( effect_stunned, 1_turns );
10817 } else if( ( str_max - 6 ) / 4 == critter->type->size ) {
10818 critter->apply_damage( this, bodypart_id( "torso" ), ( str_max - 6 ) / 4 );
10819 critter->add_effect( effect_stunned, 1_turns );
10820 }
10821 critter->check_dead_state();
10822
10823 add_msg_player_or_npc( _( "You bounce off a %s!" ), _( "<npcname> bounces off a %s!" ),
10824 critter->name() );
10825 return;
10826 }
10827
10828 if( npc *const np = g->critter_at<npc>( to ) ) {
10829 deal_damage( np, bodypart_id( "torso" ), damage_instance( DT_BASH, np->get_size() + 1 ) );
10830 add_effect( effect_stunned, 1_turns );
10831 np->deal_damage( this, bodypart_id( "torso" ), damage_instance( DT_BASH, 3 ) );
10832 add_msg_player_or_npc( _( "You bounce off %s!" ), _( "<npcname> bounces off %s!" ),
10833 np->name );
10834 np->check_dead_state();
10835 return;
10836 }
10837
10838 // If we're still in the function at this point, we're actually moving a tile!
10839 if( g->m.has_flag( "LIQUID", to ) && g->m.has_flag( TFLAG_DEEP_WATER, to ) ) {
10840 if( !is_npc() ) {
10841 avatar_action::swim( g->m, g->u, to );
10842 }
10843 // TODO: NPCs can't swim!
10844 } else if( g->m.impassable( to ) ) { // Wait, it's a wall
10845
10846 // It's some kind of wall.
10847 // TODO: who knocked us back? Maybe that creature should be the source of the damage?
10848 apply_damage( nullptr, bodypart_id( "torso" ), 3 );
10849 add_effect( effect_stunned, 2_turns );
10850 add_msg_player_or_npc( _( "You bounce off a %s!" ), _( "<npcname> bounces off a %s!" ),
10851 g->m.obstacle_name( to ) );
10852
10853 } else { // It's no wall
10854 setpos( to );
10855 }
10856}
@ TFLAG_DEEP_WATER
Definition: mapdata.h:301
void swim(map &m, avatar &you, const tripoint &p)
Handles swimming by the player.

References _, Creature::add_effect(), Creature::add_msg_player_or_npc(), apply_damage(), deal_damage(), DT_BASH, effect_stunned, g, get_map(), Creature::is_npc(), one_in(), pos(), rl_dist(), setpos(), str_max, avatar_action::swim(), TFLAG_DEEP_WATER, tripoint::x, and tripoint::y.

◆ knows_recipe()

bool Character::knows_recipe ( const recipe rec) const

Definition at line 10550 of file character.cpp.

10551{
10552 return get_learned_recipes().contains( *rec );
10553}
const recipe_subset & get_learned_recipes() const
Returns all known recipes.
bool contains(const recipe &r) const
Check if the subset contains a recipe with the specified id.

References recipe_subset::contains(), and get_learned_recipes().

Referenced by item::book_info(), complete_craft(), crafting::complete_disassemble(), avatar::create(), avatar::do_read(), find_repair_difficulty(), read_inventory_preset::get_known_recipes(), player::has_recipe(), select_crafting_recipe(), conditional_t< T >::set_u_know_recipe(), skim_book_msg(), and player::studied_all_recipes().

◆ knows_trap()

bool Character::knows_trap ( const tripoint pos) const

Definition at line 10202 of file character.cpp.

10203{
10204 const tripoint p = get_map().getabs( pos );
10205 return known_traps.count( p ) > 0;
10206}

References get_map(), map::getabs(), known_traps, and pos().

Referenced by trap::can_see(), vehicle::handle_trap(), and character_funcs::search_surroundings().

◆ leak_level()

int Character::leak_level ( const std::string &  flag) const

Definition at line 1972 of file suffer.cpp.

1973{
1974 int leak_level = 0;
1975 leak_level = inv.leak_level( flag );
1976 return leak_level;
1977}
int leak_level(const std::string &flag) const
Definition: suffer.cpp:1972
int leak_level(const std::string &flag) const
Definition: inventory.cpp:899

References inv, leak_level(), and inventory::leak_level().

Referenced by iexamine::autodoc(), iuse::geiger(), leak_level(), and suffer_from_radiation().

◆ learn_recipe()

void Character::learn_recipe ( const recipe rec)

Definition at line 10555 of file character.cpp.

10556{
10557 if( rec->never_learn ) {
10558 return;
10559 }
10560 learned_recipes->include( rec );
10561}
bool never_learn
Prevent this recipe from ever being added to the player's learned recipies ( used for special NPC cra...
Definition: recipe.h:91

References learned_recipes, and recipe::never_learn.

Referenced by debug_menu::character_edit_menu(), complete_craft(), crafting::complete_disassemble(), avatar::create(), and avatar::do_read().

◆ limb_color()

nc_color Character::limb_color ( const bodypart_id bp,
bool  bleed,
bool  bite,
bool  infect 
) const

Definition at line 5922 of file character.cpp.

5923{
5924 if( bp == bodypart_id( "num_bp" ) ) {
5925 return c_light_gray;
5926 }
5927 const body_part bp_token = bp->token;
5928 int color_bit = 0;
5929 nc_color i_color = c_light_gray;
5930 if( bleed && has_effect( effect_bleed, bp_token ) ) {
5931 color_bit += 1;
5932 }
5933 if( bite && has_effect( effect_bite, bp_token ) ) {
5934 color_bit += 10;
5935 }
5936 if( infect && has_effect( effect_infected, bp_token ) ) {
5937 color_bit += 100;
5938 }
5939 switch( color_bit ) {
5940 case 1:
5941 i_color = c_red;
5942 break;
5943 case 10:
5944 i_color = c_blue;
5945 break;
5946 case 100:
5947 i_color = c_green;
5948 break;
5949 case 11:
5950 i_color = c_magenta;
5951 break;
5952 case 101:
5953 i_color = c_yellow;
5954 break;
5955 }
5956
5957 return i_color;
5958}

References Creature::bleed(), c_blue, c_green, c_light_gray, c_magenta, c_red, c_yellow, effect_bite, effect_bleed, effect_infected, and Creature::has_effect().

Referenced by body_window(), draw_health_classic(), draw_limb2(), draw_limb_narrow(), draw_limb_wide(), and extended_description().

◆ load()

void Character::load ( const JsonObject data)
protected

Gather variables for saving.

These variables are common to both the avatar and NPCs.

Definition at line 387 of file savegame_json.cpp.

388{
390 Creature::load( data );
391
392 if( !data.read( "posx", position.x ) ) { // uh-oh.
393 debugmsg( "BAD PLAYER/NPC JSON: no 'posx'?" );
394 }
395 data.read( "posy", position.y );
396 if( !data.read( "posz", position.z ) && g != nullptr ) {
397 position.z = g->get_levz();
398 }
399 // stats
400 data.read( "str_cur", str_cur );
401 data.read( "str_max", str_max );
402 data.read( "dex_cur", dex_cur );
403 data.read( "dex_max", dex_max );
404 data.read( "int_cur", int_cur );
405 data.read( "int_max", int_max );
406 data.read( "per_cur", per_cur );
407 data.read( "per_max", per_max );
408
409 data.read( "str_bonus", str_bonus );
410 data.read( "dex_bonus", dex_bonus );
411 data.read( "per_bonus", per_bonus );
412 data.read( "int_bonus", int_bonus );
413 data.read( "omt_path", omt_path );
414
415 data.read( "base_age", init_age );
416 data.read( "base_height", init_height );
417
418 if( !data.read( "profession", prof ) || !prof.is_valid() ) {
419 // We are likely an older profession which has since been removed so just set to default.
420 // This is only cosmetic after game start.
422 }
423 data.read( "custom_profession", custom_profession );
424
425 // needs
426 data.read( "thirst", thirst );
427 data.read( "fatigue", fatigue );
428 data.read( "sleep_deprivation", sleep_deprivation );
429 data.read( "stored_calories", stored_calories );
430 data.read( "radiation", radiation );
431 data.read( "oxygen", oxygen );
432 data.read( "pkill", pkill );
433
434 data.read( "type_of_scent", type_of_scent );
435
436 if( data.has_array( "ma_styles" ) ) {
437 std::vector<matype_id> temp_styles;
438 data.read( "ma_styles", temp_styles );
439 bool temp_keep_hands_free = false;
440 data.read( "keep_hands_free", temp_keep_hands_free );
441 matype_id temp_selected_style;
442 data.read( "style_selected", temp_selected_style );
443 if( !temp_selected_style.is_valid() ) {
444 temp_selected_style = matype_id( "style_none" );
445 }
447 temp_styles, temp_selected_style, temp_keep_hands_free
448 ) );
449 } else {
450 data.read( "martial_arts_data", martial_arts_data );
451 }
452
453 JsonObject vits = data.get_object( "vitamin_levels" );
455 for( const std::pair<const vitamin_id, vitamin> &v : vitamin::all() ) {
456 if( vits.has_member( v.first.str() ) ) {
457 int lvl = vits.get_int( v.first.str() );
458 vitamin_levels[v.first] = clamp( lvl, v.first->min(), v.first->max() );
459 }
460 }
461 data.read( "consumption_history", consumption_history );
462 data.read( "activity", activity );
463 data.read( "destination_activity", destination_activity );
464 data.read( "stashed_outbounds_activity", stashed_outbounds_activity );
465 data.read( "stashed_outbounds_backlog", stashed_outbounds_backlog );
466 data.read( "backlog", backlog );
467 if( !backlog.empty() && !backlog.front().str_values.empty() && ( ( activity &&
468 activity.id() == activity_id( "ACT_FETCH_REQUIRED" ) ) || ( destination_activity &&
469 destination_activity.id() == activity_id( "ACT_FETCH_REQUIRED" ) ) ) ) {
470 requirement_data fetch_reqs;
471 data.read( "fetch_data", fetch_reqs );
472 const requirement_id req_id( backlog.front().str_values.back() );
473 requirement_data::save_requirement( fetch_reqs, req_id );
474 }
475 // npc activity on vehicles.
476 data.read( "activity_vehicle_part_index", activity_vehicle_part_index );
477 // health
478 data.read( "healthy", healthy );
479 data.read( "healthy_mod", healthy_mod );
480 data.read( "healed_24h", healed_total );
481
482 // status
483 temp_cur.fill( 5000 );
484 data.read( "temp_cur", temp_cur );
485
486 temp_conv.fill( 5000 );
487 data.read( "temp_conv", temp_conv );
488
489 frostbite_timer.fill( 0 );
490 data.read( "frostbite_timer", frostbite_timer );
491
492 body_wetness.fill( 0 );
493 data.read( "body_wetness", body_wetness );
494
495 //energy
496 data.read( "stim", stim );
497 data.read( "stamina", stamina );
498
499 data.read( "damage_bandaged", damage_bandaged );
500 data.read( "damage_disinfected", damage_disinfected );
501 data.read( "magic", magic );
502 JsonArray parray;
503
504 data.read( "traits", my_traits );
505 for( auto it = my_traits.begin(); it != my_traits.end(); ) {
506 const auto &tid = *it;
507 if( tid.is_valid() ) {
508 ++it;
509 } else {
510 debugmsg( "character %s has invalid trait %s, it will be ignored", name, tid.c_str() );
511 my_traits.erase( it++ );
512 }
513 }
514
515 data.read( "mutations", my_mutations );
516 for( auto it = my_mutations.begin(); it != my_mutations.end(); ) {
517 const trait_id &mid = it->first;
518 if( mid.is_valid() ) {
519 on_mutation_gain( mid );
520 cached_mutations.push_back( &mid.obj() );
521 ++it;
522 } else {
523 debugmsg( "character %s has invalid mutation %s, it will be ignored", name, mid.c_str() );
524 it = my_mutations.erase( it );
525 }
526 }
528
529 data.read( "my_bionics", *my_bionics );
530
531 for( auto &w : worn ) {
532 w.on_takeoff( *this );
533 }
534 worn.clear();
535 data.read( "worn", worn );
536 for( auto &w : worn ) {
537 on_item_wear( w );
538 }
539
540 if( data.has_array( "hp_cur" ) ) {
541 set_anatomy( anatomy_id( "human_anatomy" ) );
542 set_body();
543 std::array<int, 6> hp_cur;
544 data.read( "hp_cur", hp_cur );
545 std::array<int, 6> hp_max;
546 data.read( "hp_max", hp_max );
547 set_part_hp_max( bodypart_id( "head" ), hp_max[0] );
548 set_part_hp_cur( bodypart_id( "head" ), hp_cur[0] );
549
550 set_part_hp_max( bodypart_id( "torso" ), hp_max[1] );
551 set_part_hp_cur( bodypart_id( "torso" ), hp_cur[1] );
552
553 set_part_hp_max( bodypart_id( "arm_l" ), hp_max[2] );
554 set_part_hp_cur( bodypart_id( "arm_l" ), hp_cur[2] );
555
556 set_part_hp_max( bodypart_id( "arm_r" ), hp_max[3] );
557 set_part_hp_cur( bodypart_id( "arm_r" ), hp_cur[3] );
558
559 set_part_hp_max( bodypart_id( "leg_l" ), hp_max[4] );
560 set_part_hp_cur( bodypart_id( "leg_l" ), hp_cur[4] );
561
562 set_part_hp_max( bodypart_id( "leg_r" ), hp_max[5] );
563 set_part_hp_cur( bodypart_id( "leg_r" ), hp_cur[5] );
564 }
565
566
567 inv.clear();
568 if( data.has_member( "inv" ) ) {
569 JsonIn *invin = data.get_raw( "inv" );
570 inv.json_load_items( *invin );
571 }
572
574 data.read( "weapon", weapon );
575
576 data.read( "move_mode", move_mode );
577
578 if( has_effect( effect_riding ) ) {
579 int temp_id;
580 if( data.read( "mounted_creature", temp_id ) ) {
581 mounted_creature_id = temp_id;
582 mounted_creature = g->critter_tracker->from_temporary_id( temp_id );
583 } else {
584 mounted_creature = nullptr;
585 }
586 }
587
588 morale->load( data );
589 // Have to go through effects again, in case an effect gained a morale bonus
590 for( const auto &elem : *effects ) {
591 for( const std::pair<const bodypart_str_id, effect> &_effect_it : elem.second ) {
592 const effect &e = _effect_it.second;
594 }
595 }
596
597 _skills->clear();
598 for( const JsonMember member : data.get_object( "skills" ) ) {
599 member.read( ( *_skills )[skill_id( member.name() )] );
600 }
601
602 data.read( "learned_recipes", *learned_recipes );
603 autolearn_skills_stamp->clear(); // Invalidates the cache
604
605 on_stat_change( "thirst", thirst );
606 on_stat_change( "stored_calories", stored_calories );
607 on_stat_change( "fatigue", fatigue );
608 on_stat_change( "sleep_deprivation", sleep_deprivation );
609 on_stat_change( "pkill", pkill );
610 on_stat_change( "perceived_pain", get_perceived_pain() );
613
614 assign( data, "power_level", power_level, false, 0_kJ );
615 assign( data, "max_power_level", max_power_level, false, 0_kJ );
616
617 // Bionic power should not be negative!
618 if( power_level < 0_J ) {
619 power_level = 0_J;
620 }
621
622 JsonArray overmap_time_array = data.get_array( "overmap_time" );
623 overmap_time.clear();
624 while( overmap_time_array.has_more() ) {
625 point_abs_omt pt;
626 overmap_time_array.read_next( pt );
627 time_duration tdr = 0_turns;
628 overmap_time_array.read_next( tdr );
629 overmap_time[pt] = tdr;
630 }
631 data.read( "stomach", stomach );
632 data.read( "automoveroute", auto_move_route );
633
634 known_traps.clear();
635 for( JsonObject pmap : data.get_array( "known_traps" ) ) {
636 pmap.allow_omitted_members();
637 const tripoint p( pmap.get_int( "x" ), pmap.get_int( "y" ), pmap.get_int( "z" ) );
638 const std::string t = pmap.get_string( "trap" );
639 known_traps.insert( trap_map::value_type( p, t ) );
640 }
641}
bool assign(const JsonObject &jo, const std::string &name, T &val, bool strict=false, T lo=std::numeric_limits< T >::lowest(), T hi=std::numeric_limits< T >::max())
Definition: assign.h:59
void on_stat_change(const std::string &stat, int value) override
Called when a stat is changed.
Definition: character.cpp:9862
std::map< vitamin_id, int > vitamin_levels
Current deficiency/excess quantity for each vitamin.
Definition: character.h:2174
int activity_vehicle_part_index
Definition: character.h:1585
void on_effect_int_change(const efftype_id &effect_type, int intensity, const bodypart_str_id &bp) override
Called when effect intensity has been changed.
Definition: character.cpp:9833
int oxygen
Definition: character.h:1555
void on_item_wear(const item &it)
Called when an item is worn.
Definition: character.cpp:9805
void recalculate_size()
Recalculate size class of character.
Definition: mutation.cpp:246
int mounted_creature_id
Definition: character.h:1583
void set_body()
Definition: creature.cpp:1538
void set_part_hp_max(const bodypart_id &id, int set)
Definition: creature.cpp:1586
void load(const JsonObject &jsin)
bool has_more() const
Definition: json.cpp:551
bool read_next(T &t)
Definition: json.h:1113
Definition: json.h:173
Represents a member of a JsonObject.
Definition: json.h:1250
JsonObject get_object(const std::string &name) const
Definition: json.cpp:428
JsonArray get_array(const std::string &name) const
Definition: json.cpp:399
bool has_member(const std::string &name) const
Definition: json.cpp:181
JsonIn * get_raw(const std::string &name) const
Definition: json.cpp:308
int get_int(const std::string &name) const
Definition: json.cpp:349
bool has_array(const std::string &name) const
Definition: json.cpp:482
void allow_omitted_members() const
Definition: json.cpp:150
bool read(const std::string &name, T &t, bool throw_on_error=true) const
Definition: json.h:942
void json_load_items(JsonIn &jsin)
void clear()
Definition: inventory.cpp:238
This is a wrapper for implementing the pointer-to-implementation technique, see for example http://en...
Definition: pimpl.h:35
const char * c_str() const
Interface to the plain C-string of the id.
Definition: string_id.h:247
static const std::map< vitamin_id, vitamin > & all()
Get all currently loaded vitamins.
Definition: vitamin.cpp:98
std::string member
Definition: mapgen.cpp:410
static const efftype_id effect_riding("riding")
static void save_requirement(const requirement_data &req, const requirement_id &id=requirement_id::NULL_ID())
Store requirement data for future lookup.

References _skills, activity, activity_vehicle_part_index, vitamin::all(), JsonObject::allow_omitted_members(), assign(), auto_move_route, autolearn_skills_stamp, backlog, body_wetness, string_id< T >::c_str(), cached_mutations, clamp(), inventory::clear(), consumption_history, custom_profession, damage_bandaged, damage_disinfected, debugmsg, destination_activity, dex_bonus, dex_cur, dex_max, effect_riding, Creature::effects, fatigue, frostbite_timer, g, profession::generic(), JsonObject::get_array(), effect::get_bp(), effect::get_id(), JsonObject::get_int(), effect::get_intensity(), JsonObject::get_object(), get_perceived_pain(), JsonObject::get_raw(), JsonObject::has_array(), Creature::has_effect(), JsonObject::has_member(), JsonArray::has_more(), healed_total, healthy, healthy_mod, player_activity::id(), init_age, init_height, int_bonus, int_cur, int_max, inv, string_id< T >::is_valid(), inventory::json_load_items(), known_traps, learned_recipes, Creature::load(), magic, martial_arts_data, matype_id, max_power_level, mapgen_defer::member, morale, mounted_creature, mounted_creature_id, move_mode, my_bionics, my_mutations, my_traits, name, string_id< T >::obj(), omt_path, on_effect_int_change(), on_item_wear(), on_mutation_gain(), on_stat_change(), overmap_time, oxygen, per_bonus, per_cur, per_max, pkill, position, power_level, prof, radiation, JsonObject::read(), JsonArray::read_next(), recalc_sight_limits(), recalculate_size(), reset_encumbrance(), requirement_data::save_requirement(), Creature::set_anatomy(), Creature::set_body(), Creature::set_part_hp_cur(), Creature::set_part_hp_max(), skill_id, sleep_deprivation, stamina, calendar::start_of_cataclysm, stashed_outbounds_activity, stashed_outbounds_backlog, stim, stomach, stored_calories, str_bonus, str_cur, str_max, temp_conv, temp_cur, thirst, type_of_scent, vitamin_levels, weapon, worn, tripoint::x, tripoint::y, and tripoint::z.

Referenced by player::load().

◆ mabuff_armor_bonus()

int Character::mabuff_armor_bonus ( damage_type  type) const

Returns the armor bonus against given type from martial arts buffs.

Definition at line 1125 of file martialarts.cpp.

1126{
1127 int ret = 0;
1128 accumulate_ma_buff_effects( *effects, [&ret, type, this]( const ma_buff & b, const effect & d ) {
1129 ret += d.get_intensity() * b.armor_bonus( *this, type );
1130 } );
1131 return ret;
1132}
static void accumulate_ma_buff_effects(const C &container, F f)

References accumulate_ma_buff_effects(), b, Creature::effects, effect::get_intensity(), cata::hash64_detail::ret, and type.

Referenced by passive_absorb_hit().

◆ mabuff_arpen_bonus()

int Character::mabuff_arpen_bonus ( damage_type  type) const

Returns the arpen bonus from martial arts buffs.

Definition at line 1117 of file martialarts.cpp.

1118{
1119 int ret = 0;
1120 accumulate_ma_buff_effects( *effects, [&ret, type, this]( const ma_buff & b, const effect & d ) {
1121 ret += d.get_intensity() * b.arpen_bonus( *this, type );
1122 } );
1123 return ret;
1124}

References accumulate_ma_buff_effects(), b, Creature::effects, effect::get_intensity(), cata::hash64_detail::ret, and type.

Referenced by roll_bash_damage(), roll_cut_damage(), and roll_stab_damage().

◆ mabuff_attack_cost_mult()

float Character::mabuff_attack_cost_mult ( ) const

Returns the multiplier on move cost of attacks.

Definition at line 1159 of file martialarts.cpp.

1160{
1161 float ret = 1.0f;
1162 accumulate_ma_buff_effects( *effects, [&ret, this]( const ma_buff & b, const effect & d ) {
1163 // This is correct, so that a 20% buff (1.2) plus a 20% buff (1.2)
1164 // becomes 1.4 instead of 2.4 (which would be a 240% buff)
1165 ret *= d.get_intensity() * ( b.bonuses.get_mult( *this,
1166 affected_stat::MOVE_COST ) - 1 ) + 1;
1167 } );
1168 return ret;
1169}

References accumulate_ma_buff_effects(), b, Creature::effects, effect::get_intensity(), MOVE_COST, and cata::hash64_detail::ret.

Referenced by attack_cost().

◆ mabuff_attack_cost_penalty()

int Character::mabuff_attack_cost_penalty ( ) const

Returns the flat penalty to move cost of attacks.

If negative, that's a bonus. Applied after multiplier.

Definition at line 1151 of file martialarts.cpp.

1152{
1153 int ret = 0;
1154 accumulate_ma_buff_effects( *effects, [&ret, this]( const ma_buff & b, const effect & d ) {
1155 ret += d.get_intensity() * b.bonuses.get_flat( *this, affected_stat::MOVE_COST );
1156 } );
1157 return ret;
1158}

References accumulate_ma_buff_effects(), b, Creature::effects, effect::get_intensity(), MOVE_COST, and cata::hash64_detail::ret.

Referenced by attack_cost().

◆ mabuff_block_bonus()

int Character::mabuff_block_bonus ( ) const

Returns the block bonus from martial arts buffs.

Definition at line 1101 of file martialarts.cpp.

1102{
1103 int ret = 0;
1104 accumulate_ma_buff_effects( *effects, [&ret, this]( const ma_buff & b, const effect & d ) {
1105 ret += d.get_intensity() * b.block_bonus( *this );
1106 } );
1107 return ret;
1108}

References accumulate_ma_buff_effects(), b, Creature::effects, effect::get_intensity(), and cata::hash64_detail::ret.

Referenced by block_hit().

◆ mabuff_damage_bonus()

int Character::mabuff_damage_bonus ( damage_type  type) const

Returns the flat damage bonus to given type from martial arts buffs, applied after the multiplier.

Definition at line 1143 of file martialarts.cpp.

1144{
1145 int ret = 0;
1146 accumulate_ma_buff_effects( *effects, [&ret, type, this]( const ma_buff & b, const effect & d ) {
1147 ret += d.get_intensity() * b.damage_bonus( *this, type );
1148 } );
1149 return ret;
1150}

References accumulate_ma_buff_effects(), b, Creature::effects, effect::get_intensity(), cata::hash64_detail::ret, and type.

Referenced by roll_bash_damage(), roll_cut_damage(), and roll_stab_damage().

◆ mabuff_damage_mult()

float Character::mabuff_damage_mult ( damage_type  type) const

Returns the damage multiplier to given type from martial arts buffs.

Definition at line 1133 of file martialarts.cpp.

1134{
1135 float ret = 1.f;
1136 accumulate_ma_buff_effects( *effects, [&ret, type, this]( const ma_buff & b, const effect & d ) {
1137 // This is correct, so that a 20% buff (1.2) plus a 20% buff (1.2)
1138 // becomes 1.4 instead of 2.4 (which would be a 240% buff)
1139 ret *= d.get_intensity() * ( b.damage_mult( *this, type ) - 1 ) + 1;
1140 } );
1141 return ret;
1142}

References accumulate_ma_buff_effects(), b, Creature::effects, effect::get_intensity(), cata::hash64_detail::ret, and type.

Referenced by roll_bash_damage(), roll_cut_damage(), and roll_stab_damage().

◆ mabuff_dodge_bonus()

float Character::mabuff_dodge_bonus ( ) const

Returns the dodge bonus from martial arts buffs.

Definition at line 1093 of file martialarts.cpp.

1094{
1095 float ret = 0;
1096 accumulate_ma_buff_effects( *effects, [&ret, this]( const ma_buff & b, const effect & d ) {
1097 ret += d.get_intensity() * b.dodge_bonus( *this );
1098 } );
1099 return ret;
1100}

References accumulate_ma_buff_effects(), b, Creature::effects, effect::get_intensity(), and cata::hash64_detail::ret.

Referenced by reset_stats().

◆ mabuff_speed_bonus()

int Character::mabuff_speed_bonus ( ) const

Returns the speed bonus from martial arts buffs.

Definition at line 1109 of file martialarts.cpp.

1110{
1111 int ret = 0;
1112 accumulate_ma_buff_effects( *effects, [&ret, this]( const ma_buff & b, const effect & d ) {
1113 ret += d.get_intensity() * b.speed_bonus( *this );
1114 } );
1115 return ret;
1116}

References accumulate_ma_buff_effects(), b, Creature::effects, effect::get_intensity(), and cata::hash64_detail::ret.

Referenced by recalc_speed_bonus().

◆ mabuff_tohit_bonus()

float Character::mabuff_tohit_bonus ( ) const

Returns the to hit bonus from martial arts buffs.

Definition at line 1085 of file martialarts.cpp.

1086{
1087 float ret = 0;
1088 accumulate_ma_buff_effects( *effects, [&ret, this]( const ma_buff & b, const effect & ) {
1089 ret += b.hit_bonus( *this );
1090 } );
1091 return ret;
1092}

References accumulate_ma_buff_effects(), b, Creature::effects, and cata::hash64_detail::ret.

Referenced by get_melee_hit_base().

◆ made_of()

bool Character::made_of ( const material_id m) const
overridevirtual

Implements Creature.

Definition at line 6208 of file character.cpp.

6209{
6210 // TODO: check for mutations that change this.
6211 return std::find( fleshy.begin(), fleshy.end(), m ) != fleshy.end();
6212}
static const std::vector< material_id > fleshy
Definition: character.h:775

References detail::find(), and fleshy.

◆ made_of_any()

bool Character::made_of_any ( const std::set< material_id > &  ms) const
overridevirtual

Implements Creature.

Definition at line 6213 of file character.cpp.

6214{
6215 // TODO: check for mutations that change this.
6216 return std::any_of( fleshy.begin(), fleshy.end(), [&ms]( const material_id & e ) {
6217 return ms.count( e );
6218 } );
6219}
constexpr scale ms
Definition: coordinates.h:30

References fleshy, and coords::ms.

◆ max_stored_kcal()

◆ meets_requirements()

bool Character::meets_requirements ( const item it,
const item context = item() 
) const

Checks whether the character meets overall requirements to be able to use the item.

Definition at line 3507 of file character.cpp.

3508{
3509 const auto &ctx = !context.is_null() ? context : it;
3511}
bool meets_stat_requirements(const item &it) const
Checks whether the character's stats meets the stats required by the item.
Definition: character.cpp:3499

References item::is_null(), meets_skill_requirements(), meets_stat_requirements(), itype::min_skills, and item::type.

Referenced by can_use(), gunmod_inventory_preset::get_denial(), and item::gun_range().

◆ meets_skill_requirements() [1/2]

bool Character::meets_skill_requirements ( const construction con) const

Checks whether the character's skills meet the required.

Definition at line 3491 of file character.cpp.

3492{
3493 return std::all_of( con.required_skills.begin(), con.required_skills.end(),
3494 [&]( const std::pair<skill_id, int> &pr ) {
3495 return get_skill_level( pr.first ) >= pr.second;
3496 } );
3497}
std::map< skill_id, int > required_skills
Skill->skill level mapping.
Definition: construction.h:72

References construction::required_skills.

◆ meets_skill_requirements() [2/2]

bool Character::meets_skill_requirements ( const std::map< skill_id, int > &  req,
const item context = item() 
) const

Checks whether the character's skills meet the required.

Definition at line 3485 of file character.cpp.

3487{
3488 return _skills->meets_skill_requirements( req, context );
3489}

References _skills.

Referenced by activity_handlers::build_do_turn(), can_learn_by_disassembly(), find_base_construction(), get_learned_recipes(), meets_requirements(), and player_can_build().

◆ meets_stat_requirements()

bool Character::meets_stat_requirements ( const item it) const

Checks whether the character's stats meets the stats required by the item.

Definition at line 3499 of file character.cpp.

3500{
3501 return ( it.has_flag( flag_STR_DRAW ) || get_str() >= it.get_min_str() ) &&
3502 get_dex() >= it.type->min_dex &&
3503 get_int() >= it.type->min_int &&
3504 get_per() >= it.type->min_per;
3505}
static const std::string flag_STR_DRAW("STR_DRAW")

References flag_STR_DRAW(), get_dex(), get_int(), item::get_min_str(), get_per(), get_str(), item::has_flag(), itype::min_dex, itype::min_int, itype::min_per, and item::type.

Referenced by meets_requirements().

◆ melee_attack()

void Character::melee_attack ( Creature t,
bool  allow_special,
const matec_id force_technique = nullptr,
bool  allow_unarmed = true 
)

Sets up a melee attack and handles melee attack function calls.

Parameters
tCreature to attack
allow_specialwhether non-forced martial art technique or mutation attack should be possible with this attack.
force_techniquespecial technique to use in attack (leave as nullptr to use random technique).
allow_unarmedalways uses the wielded weapon regardless of martialarts style
Melee reduces stamina cost of melee attacks

Definition at line 387 of file melee.cpp.

389{
391 int hit_spread = t.deal_melee_attack( this, hit_roll() );
392 if( !t.is_player() ) {
393 // TODO: Per-NPC tracking? Right now monster hit by either npc or player will draw aggro...
394 t.add_effect( effect_hit_by_player, 10_minutes ); // Flag as attacked by us for AI
395 }
396 if( is_mounted() ) {
397 auto mons = mounted_creature.get();
398 if( mons->has_flag( MF_RIDEABLE_MECH ) ) {
399 if( !mons->check_mech_powered() ) {
400 add_msg( m_bad, _( "The %s has dead batteries and will not move its arms." ),
401 mons->get_name() );
402 return;
403 }
404 if( mons->type->has_special_attack( "SMASH" ) && one_in( 3 ) ) {
405 add_msg( m_info, _( "The %s hisses as its hydraulic arm pumps forward!" ),
406 mons->get_name() );
407 mattack::smash_specific( mons, &t );
408 } else {
409 mons->use_mech_power( -2 );
410 mons->melee_attack( t );
411 }
412 mod_moves( -mons->type->attack_cost );
413 return;
414 }
415 }
416 item &cur_weapon = allow_unarmed ? used_weapon() : weapon;
417
418 if( cur_weapon.attack_cost() > attack_cost( cur_weapon ) * 20 ) {
419 add_msg( m_bad, _( "This weapon is too unwieldy to attack with!" ) );
420 return;
421 }
422
423 int move_cost = attack_cost( cur_weapon );
424
425 if( hit_spread < 0 ) {
426 int stumble_pen = stumble( *this, cur_weapon );
427 sfx::generate_melee_sound( pos(), t.pos(), false, false );
428 if( is_player() ) { // Only display messages if this is the player
429
430 if( one_in( 2 ) ) {
431 const std::string reason_for_miss = get_miss_reason();
432 if( !reason_for_miss.empty() ) {
433 add_msg( reason_for_miss );
434 }
435 }
436
437 if( can_miss_recovery( cur_weapon ) ) {
438 ma_technique tec = martial_arts_data->get_miss_recovery_tec( cur_weapon );
439 add_msg( _( tec.avatar_message ), t.disp_name() );
440 } else if( stumble_pen >= 60 ) {
441 add_msg( m_bad, _( "You miss and stumble with the momentum." ) );
442 } else if( stumble_pen >= 10 ) {
443 add_msg( _( "You swing wildly and miss." ) );
444 } else {
445 add_msg( _( "You miss." ) );
446 }
447 } else if( g->u.sees( *this ) ) {
448 if( stumble_pen >= 60 ) {
449 add_msg( _( "%s misses and stumbles with the momentum." ), name );
450 } else if( stumble_pen >= 10 ) {
451 add_msg( _( "%s swings wildly and misses." ), name );
452 } else {
453 add_msg( _( "%s misses." ), name );
454 }
455 }
456
457 // Practice melee and relevant weapon skill (if any) except when using CQB bionic
458 if( !has_active_bionic( bio_cqb ) ) {
459 melee_train( *this, 2, 5, cur_weapon );
460 }
461
462 // Cap stumble penalty, heavy weapons are quite weak already
463 move_cost += std::min( 60, stumble_pen );
464 if( martial_arts_data->has_miss_recovery_tec( cur_weapon ) ) {
465 move_cost /= 2;
466 }
467
468 // trigger martial arts on-miss effects
469 martial_arts_data->ma_onmiss_effects( *this );
470 } else {
472 // Remember if we see the monster at start - it may change
473 const bool seen = g->u.sees( t );
474 // Start of attacks.
475 const bool critical_hit = scored_crit( t.dodge_roll(), cur_weapon );
476 if( critical_hit ) {
478 }
480 roll_all_damage( critical_hit, d, false, cur_weapon );
481
482 const bool has_force_technique = force_technique;
483
484 // Pick one or more special attacks
485 matec_id technique_id;
486 if( allow_special && !has_force_technique ) {
487 technique_id = pick_technique( t, cur_weapon, critical_hit, false, false );
488 } else if( has_force_technique ) {
489 technique_id = *force_technique;
490 } else {
491 technique_id = tec_none;
492 }
493
494 // if you have two broken arms you aren't doing any martial arts
495 // and your hits are not going to hurt very much
496 if( get_working_arm_count() < 1 ) {
497 technique_id = tec_none;
498 d.mult_damage( 0.1 );
499 }
500 // polearms and pikes (but not spears) do less damage to adjacent targets
501 if( cur_weapon.reach_range( *this ) > 1 && !reach_attacking &&
502 cur_weapon.has_flag( "POLEARM" ) ) {
503 d.mult_damage( 0.7 );
504 }
505
506 const ma_technique &technique = technique_id.obj();
507
508 // Handles effects as well; not done in melee_affect_*
509 if( technique.id != tec_none ) {
510 perform_technique( technique, t, d, move_cost );
511 }
512
513 // Proceed with melee attack.
514 if( !t.is_dead_state() ) {
515 // Handles speed penalties to monster & us, etc
516 std::string specialmsg = melee_special_effects( t, d, cur_weapon );
517
518 // gets overwritten with the dealt damage values
519 dealt_damage_instance dealt_dam;
520 dealt_damage_instance dealt_special_dam;
521 if( allow_special ) {
522 perform_special_attacks( t, dealt_special_dam );
523 }
524 t.deal_melee_hit( this, hit_spread, critical_hit, d, dealt_dam );
525 if( dealt_special_dam.type_damage( DT_CUT ) > 0 ||
526 dealt_special_dam.type_damage( DT_STAB ) > 0 ||
527 ( cur_weapon.is_null() && ( dealt_dam.type_damage( DT_CUT ) > 0 ||
528 dealt_dam.type_damage( DT_STAB ) > 0 ) ) ) {
529 if( has_trait( trait_POISONOUS ) ) {
530 add_msg_if_player( m_good, _( "You poison %s!" ), t.disp_name() );
531 t.add_effect( effect_poison, 6_turns );
532 } else if( has_trait( trait_POISONOUS2 ) ) {
533 add_msg_if_player( m_good, _( "You inject your venom into %s!" ),
534 t.disp_name() );
535 t.add_effect( effect_badpoison, 6_turns );
536 }
537 }
538
539 // Make a rather quiet sound, to alert any nearby monsters
540 if( !is_quiet() ) { // check martial arts silence
541 //sound generated later
542 sounds::sound( pos(), 8, sounds::sound_t::combat, "whack!" );
543 }
544 std::string material = "flesh";
545 if( t.is_monster() ) {
546 const monster *m = dynamic_cast<const monster *>( &t );
547 if( m->made_of( material_id( "steel" ) ) ) {
548 material = "steel";
549 }
550 }
551 sfx::generate_melee_sound( pos(), t.pos(), true, t.is_monster(), material );
552 int dam = dealt_dam.total_damage();
554
555 // Practice melee and relevant weapon skill (if any) except when using CQB bionic
556 if( !has_active_bionic( bio_cqb ) ) {
557 melee_train( *this, 5, 10, cur_weapon );
558 }
559
560 if( dam >= 5 && has_artifact_with( AEP_SAP_LIFE ) ) {
561 healall( rng( dam / 10, dam / 5 ) );
562 }
563
564 // Treat monster as seen if we see it before or after the attack
565 if( seen || g->u.sees( t ) ) {
566 std::string message = melee_message( technique, *this, dealt_dam );
567 player_hit_message( this, message, t, dam, critical_hit );
568 } else {
569 add_msg_player_or_npc( m_good, _( "You hit something." ),
570 _( "<npcname> hits something." ) );
571 }
572
573 if( !specialmsg.empty() ) {
574 add_msg_if_player( m_neutral, specialmsg );
575 }
576
577 if( critical_hit ) {
578 // trigger martial arts on-crit effects
579 martial_arts_data->ma_oncrit_effects( *this );
580 }
581
582 }
583
585 did_hit( t );
586
587 if( t.is_dead_state() ) {
588 // trigger martial arts on-kill effects
589 martial_arts_data->ma_onkill_effects( *this );
590 }
591 }
592
593 const int melee = get_skill_level( skill_melee );
594
595 // Previously calculated as 2_gram * std::max( 1, str_cur )
596 // using 16_gram normalizes it to 8 str. Same effort expenditure
597 // for each strike, regardless of weight. This is compensated
598 // for by the additional move cost as weapon weight increases
599 const int weight_cost = cur_weapon.weight() / ( 16_gram );
600 const int encumbrance_cost = roll_remainder( ( encumb( bp_arm_l ) + encumb( bp_arm_r ) ) *
601 2.0f );
602 const int deft_bonus = hit_spread < 0 && has_trait( trait_DEFT ) ? 50 : 0;
603 const float skill_cost = std::max( 0.667f, static_cast<float>( ( 30.0f - melee ) / 30.0f ) );
604 /** @EFFECT_MELEE reduces stamina cost of melee attacks */
605 const int mod_sta = ( weight_cost + encumbrance_cost - deft_bonus + 50 ) * -1 * skill_cost;
606 mod_stamina( std::min( -50, mod_sta ) );
607 add_msg( m_debug, "Stamina burn: %d", std::min( -50, mod_sta ) );
609 // trigger martial arts on-attack effects
610 martial_arts_data->ma_onattack_effects( *this );
611 // some things (shattering weapons) can harm the attacking creature.
613 if( t.as_character() ) {
615 t.as_character()->on_hit( this, bodypart_id( "num_bp" ), &dp );
616 }
617 return;
618}
int attack_cost(const item &weap) const
Returns cost (in moves) of attacking with given item (no modifiers, like stuck)
Definition: melee.cpp:2220
bool can_miss_recovery(const item &weap) const
Returns true if the player is able to use a miss recovery technique.
std::string melee_special_effects(Creature &t, damage_instance &d, item &weap)
Handles combat effects, returns a string of any valid combat effect messages.
Definition: melee.cpp:1817
void perform_special_attacks(Creature &t, dealt_damage_instance &dealt_dam)
Performs special attacks and their effects (poisonous, stinger, etc.)
Definition: melee.cpp:1790
float hit_roll() const override
Returns the player's basic hit roll that is compared to the target's dodge roll.
Definition: melee.cpp:300
bool scored_crit(float target_dodge, const item &weap) const
Returns true if the player scores a critical hit.
Definition: melee.cpp:726
bool reach_attacking
Definition: character.h:610
void did_hit(Creature &target)
Handles special effects when the Character hits a Creature.
Definition: character.cpp:8247
void on_hit(Creature *source, bodypart_id bp_hit, dealt_projectile_attack const *proj) override
This creature just got hit by an attack - possibly special/ranged attack - from source.
Definition: character.cpp:8252
void perform_technique(const ma_technique &technique, Creature &t, damage_instance &di, int &move_cost)
Definition: melee.cpp:1369
std::string get_miss_reason()
Returns an explanation for why the player would miss a melee attack.
Definition: melee.cpp:332
void roll_all_damage(bool crit, damage_instance &di, bool average, const item &weap) const
Adds all 3 types of physical damage to instance.
Definition: melee.cpp:354
bool is_quiet() const
Returns true if the player has quiet melee attacks.
virtual bool is_monster() const
Definition: creature.h:101
virtual Character * as_character()
Definition: creature.h:116
virtual int deal_melee_attack(Creature *source, int hitroll)
Definition: creature.cpp:503
virtual float dodge_roll()=0
virtual void deal_melee_hit(Creature *source, int hit_spread, bool critical_hit, const damage_instance &dam, dealt_damage_instance &dealt_dam)
Definition: creature.cpp:522
virtual bool is_dead_state() const =0
int reach_range(const Character &guy) const
Max range of melee attack this weapon can be used for.
Definition: item.cpp:5270
matec_id id
Definition: martialarts.h:70
std::string avatar_message
Definition: martialarts.h:85
bool made_of(const material_id &m) const override
Definition: monster.cpp:987
@ AEP_SAP_LIFE
Definition: enums.h:119
void player_hit_message(Character *attacker, const std::string &message, Creature &t, int dam, bool crit=false)
Definition: melee.cpp:2158
static const efftype_id effect_badpoison("badpoison")
std::string melee_message(const ma_technique &tec, Character &p, const dealt_damage_instance &ddi)
Definition: melee.cpp:2040
static const efftype_id effect_hit_by_player("hit_by_player")
int stumble(Character &u, const item &weap)
Definition: melee.cpp:710
static const trait_id trait_POISONOUS("POISONOUS")
static void melee_train(Character &p, int lo, int hi, const item &weap)
Definition: melee.cpp:362
static const trait_id trait_DEFT("DEFT")
static const efftype_id effect_poison("poison")
static const trait_id trait_POISONOUS2("POISONOUS2")
void smash_specific(monster *z, Creature *target)
Definition: monattack.cpp:1102
void generate_melee_sound(const tripoint &source, const tripoint &target, bool hit, bool targ_mon=false, const std::string &material="flesh")
Definition: sounds.cpp:1605
int actual_crit_count
Definition: melee.h:13

References _, melee_statistic_data::actual_crit_count, Creature::add_effect(), add_msg(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), AEP_SAP_LIFE, Creature::as_character(), item::attack_cost(), attack_cost(), melee_statistic_data::attack_count, ma_technique::avatar_message, bio_cqb, bp_arm_l, bp_arm_r, can_miss_recovery(), Creature::check_dead_state(), sounds::combat, melee_statistic_data::damage_amount, Creature::deal_melee_attack(), Creature::deal_melee_hit(), did_hit(), Creature::disp_name(), Creature::dodge_roll(), DT_CUT, DT_STAB, effect_badpoison, effect_hit_by_player, effect_poison, encumb(), g, sfx::generate_melee_sound(), get_miss_reason(), get_skill_level(), get_working_arm_count(), has_active_bionic(), has_artifact_with(), item::has_flag(), has_trait(), healall(), melee_statistic_data::hit_count, hit_roll(), ma_technique::id, Creature::is_dead_state(), Creature::is_monster(), is_mounted(), item::is_null(), Creature::is_player(), is_quiet(), m_bad, m_debug, m_good, m_info, m_neutral, monster::made_of(), martial_arts_data, melee_message(), melee_special_effects(), melee::melee_stats, melee_train(), mapgen_defer::message, MF_RIDEABLE_MECH, Creature::mod_moves(), mod_stamina(), mounted_creature, move_cost(), damage_instance::mult_damage(), name, string_id< T >::obj(), on_hit(), one_in(), perform_special_attacks(), perform_technique(), pick_technique(), player_hit_message(), Creature::pos(), pos(), reach_attacking, item::reach_range(), rng(), roll_all_damage(), roll_remainder(), scored_crit(), skill_melee, mattack::smash_specific(), sounds::sound(), stumble(), tec_none, dealt_damage_instance::total_damage(), trait_DEFT, trait_POISONOUS, trait_POISONOUS2, dealt_damage_instance::type_damage(), used_weapon(), weapon, and item::weight().

Referenced by block_hit(), npc::execute_action(), monexamine::mfriend_menu(), avatar_action::move(), npc::move_to(), game::npc_menu(), on_dodge(), perform_technique(), monexamine::pet_menu(), and reach_attack().

◆ melee_special_effects()

std::string Character::melee_special_effects ( Creature t,
damage_instance d,
item weap 
)

Handles combat effects, returns a string of any valid combat effect messages.

Strength increases chance of breaking glass weapons (NEGATIVE)

Definition at line 1817 of file melee.cpp.

1818{
1819 std::string dump;
1820
1821 std::string target = t.disp_name();
1822
1823 const bionic_id bio_shock( "bio_shock" );
1825 ( !is_armed() || weapon.conductive() ) ) {
1827 d.add_damage( DT_ELECTRIC, rng( 2, 10 ) );
1828
1829 if( is_player() ) {
1830 dump += string_format( _( "You shock %s." ), target ) + "\n";
1831 } else {
1832 add_msg_if_npc( _( "<npcname> shocks %s." ), target );
1833 }
1834 }
1835
1836 const bionic_id bio_heat_absorb( "bio_heat_absorb" );
1837 if( has_active_bionic( bio_heat_absorb ) && !is_armed() && t.is_warm() ) {
1839 d.add_damage( DT_COLD, 3 );
1840 if( is_player() ) {
1841 dump += string_format( _( "You drain %s's body heat." ), target ) + "\n";
1842 } else {
1843 add_msg_if_npc( _( "<npcname> drains %s's body heat!" ), target );
1844 }
1845 }
1846
1847 if( weapon.has_flag( "FLAMING" ) ) {
1848 d.add_damage( DT_HEAT, rng( 1, 8 ) );
1849
1850 if( is_player() ) {
1851 dump += string_format( _( "You burn %s." ), target ) + "\n";
1852 } else {
1853 add_msg_player_or_npc( _( "<npcname> burns %s." ), target );
1854 }
1855 }
1856
1857 //Hurting the wielder from poorly-chosen weapons
1858 if( weap.has_flag( "HURT_WHEN_WIELDED" ) && x_in_y( 2, 3 ) ) {
1859 add_msg_if_player( m_bad, _( "The %s cuts your hand!" ), weap.tname() );
1860 deal_damage( nullptr, bodypart_id( "hand_r" ), damage_instance::physical( 0,
1861 weap.damage_melee( DT_CUT ), 0 ) );
1862 if( weap.is_two_handed( *this ) ) { // Hurt left hand too, if it was big
1863 deal_damage( nullptr, bodypart_id( "hand_l" ), damage_instance::physical( 0,
1864 weap.damage_melee( DT_CUT ), 0 ) );
1865 }
1866 }
1867
1868 const int vol = weap.volume() / 250_ml;
1869 // Glass weapons shatter sometimes
1870 if( weap.made_of( material_id( "glass" ) ) &&
1871 /** @EFFECT_STR increases chance of breaking glass weapons (NEGATIVE) */
1872 rng( 0, vol + 8 ) < vol + str_cur ) {
1873 if( is_player() ) {
1874 dump += string_format( _( "Your %s shatters!" ), weap.tname() ) + "\n";
1875 } else {
1876 add_msg_player_or_npc( m_bad, _( "Your %s shatters!" ),
1877 _( "<npcname>'s %s shatters!" ),
1878 weap.tname() );
1879 }
1880
1881 sounds::sound( pos(), 16, sounds::sound_t::combat, "Crack!", true, "smash_success",
1882 "smash_glass_contents" );
1883 // Dump its contents on the ground
1884 weap.contents.spill_contents( pos() );
1885 // Take damage
1886 deal_damage( nullptr, bodypart_id( "arm_r" ), damage_instance::physical( 0, rng( 0, vol * 2 ),
1887 0 ) );
1888 if( weap.is_two_handed( *this ) ) { // Hurt left arm too, if it was big
1889 //redeclare shatter_dam because deal_damage mutates it
1890 deal_damage( nullptr, bodypart_id( "arm_l" ), damage_instance::physical( 0, rng( 0, vol * 2 ),
1891 0 ) );
1892 }
1893 d.add_damage( DT_CUT, rng( 0, 5 + static_cast<int>( vol * 1.5 ) ) ); // Hurt the monster extra
1894 remove_weapon();
1895 }
1896
1897 if( !t.is_hallucination() ) {
1898 handle_melee_wear( weap );
1899 }
1900
1901 // on-hit effects for martial arts
1902 martial_arts_data->ma_onhit_effects( *this );
1903
1904 return dump;
1905}
item remove_weapon()
Definition: character.cpp:2486
virtual bool is_warm() const
Definition: creature.cpp:966
int damage_melee(damage_type dt) const
Damage of given type caused when this item is used as melee weapon.
Definition: item.cpp:5193
static const bionic_id bio_shock("bio_shock")
static const bionic_id bio_heat_absorb("bio_heat_absorb")

References _, damage_instance::add_damage(), Creature::add_msg_if_npc(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), bio_heat_absorb, bio_shock, sounds::combat, item::conductive(), item::contents, item::damage_melee(), deal_damage(), Creature::disp_name(), DT_COLD, DT_CUT, DT_ELECTRIC, DT_HEAT, get_power_level(), handle_melee_wear(), has_active_bionic(), item::has_flag(), is_armed(), Creature::is_hallucination(), Creature::is_player(), item::is_two_handed(), Creature::is_warm(), m_bad, item::made_of(), martial_arts_data, mod_power_level(), damage_instance::physical(), pos(), bionic_data::power_trigger, remove_weapon(), rng(), sounds::sound(), item_contents::spill_contents(), str_cur, string_format(), item::tname(), item::volume(), weapon, and x_in_y().

Referenced by melee_attack().

◆ mend()

void Character::mend ( int  rate_multiplier)

Handles the chance for broken limbs to spontaneously heal to 1 HP.

Definition at line 1607 of file suffer.cpp.

1608{
1609 // Wearing splints can slowly mend a broken limb back to 1 hp.
1610 bool any_broken = false;
1611 for( const bodypart_id &bp : get_all_body_parts() ) {
1612 if( is_limb_broken( bp ) ) {
1613 any_broken = true;
1614 break;
1615 }
1616 }
1617
1618 if( !any_broken ) {
1619 return;
1620 }
1621
1622 double healing_factor = 1.0;
1623 // Studies have shown that alcohol and tobacco use delay fracture healing time
1624 // Being under effect is 50% slowdown
1625 // Being addicted but not under effect scales from 25% slowdown to 75% slowdown
1626 // The improvement from being intoxicated over withdrawal is intended
1627 if( has_effect( effect_cig ) ) {
1628 healing_factor *= 0.5;
1629 } else {
1630 healing_factor *= addiction_scaling( 0.25f, 0.75f, addiction_level( add_type::CIG ) );
1631 }
1632
1633 if( has_effect( effect_drunk ) ) {
1634 healing_factor *= 0.5;
1635 } else {
1636 healing_factor *= addiction_scaling( 0.25f, 0.75f, addiction_level( add_type::ALCOHOL ) );
1637 }
1638
1639 if( get_rad() > 0 && !has_trait( trait_RADIOGENIC ) ) {
1640 healing_factor *= clamp( ( 1000.0f - get_rad() ) / 1000.0f, 0.0f, 1.0f );
1641 }
1642
1643 // Bed rest speeds up mending
1644 if( has_effect( effect_sleep ) ) {
1645 healing_factor *= 4.0;
1646 } else if( get_fatigue() > fatigue_levels::dead_tired ) {
1647 // but being dead tired does not...
1648 healing_factor *= 0.75;
1649 } else {
1650 // If not dead tired, resting without sleep also helps
1651 healing_factor *= 1.0f + rest_quality();
1652 }
1653
1654 // Being healthy helps.
1655 healing_factor *= 1.0f + get_healthy() / 200.0f;
1656
1657 // Very hungry starts lowering the chance
1658 // square rooting the value makes the numbers drop off faster when below 1
1659 healing_factor *= std::sqrt( static_cast<float>( get_stored_kcal() ) / static_cast<float>
1660 ( max_stored_kcal() ) );
1661 // Similar for thirst - starts at very thirsty, drops to 0 at parched
1662 healing_factor *= 1.0f - clamp( 1.0f * ( get_thirst() - thirst_levels::very_thirsty ) /
1663 +thirst_levels::parched, 0.0f, 1.0f );
1664
1665 // Mutagenic healing factor!
1666 bool needs_splint = true;
1667
1668 healing_factor *= mutation_value( "mending_modifier" );
1669
1670 if( has_trait( trait_REGEN_LIZ ) ) {
1671 needs_splint = false;
1672 }
1673
1674 add_msg( m_debug, "Limb mend healing factor: %.2f", healing_factor );
1675 if( healing_factor <= 0.0f ) {
1676 // The section below assumes positive healing rate
1677 return;
1678 }
1679
1680 for( const bodypart_id &bp : get_all_body_parts() ) {
1681 const bool broken = is_limb_broken( bp );
1682 if( !broken ) {
1683 continue;
1684 }
1685
1686 if( needs_splint && !worn_with_flag( "SPLINT", bp ) ) {
1687 continue;
1688 }
1689
1690 const time_duration dur_inc = 1_turns * roll_remainder( rate_multiplier * healing_factor );
1691 auto &eff = get_effect( effect_mending, bp->token );
1692 if( eff.is_null() ) {
1693 add_effect( effect_mending, dur_inc, bp->token );
1694 continue;
1695 }
1696
1697 eff.set_duration( eff.get_duration() + dur_inc );
1698
1699 if( eff.get_duration() >= eff.get_max_duration() ) {
1700 set_part_hp_cur( bp, 1 );
1701 remove_effect( effect_mending, bp->token );
1702 g->events().send<event_type::broken_bone_mends>( getID(), bp->token );
1703 //~ %s is bodypart
1704 add_msg_if_player( m_good, _( "Your %s has started to mend!" ),
1705 body_part_name( bp ) );
1706 }
1707 }
1708}
float rest_quality() const
Returns >0 if character is sitting/lying and relatively inactive.
Definition: character.cpp:6410
int addiction_level(add_type type) const
Returns the intensity of the specified addiction.
Definition: suffer.cpp:1963
@ broken
Definition: enums.h:330
static const efftype_id effect_drunk("drunk")
static const trait_id trait_REGEN_LIZ("REGEN_LIZ")
static const efftype_id effect_cig("cig")
static const efftype_id effect_sleep("sleep")
static float addiction_scaling(float at_min, float at_max, float add_lvl)
Definition: suffer.cpp:173
static const efftype_id effect_mending("mending")
static const trait_id trait_RADIOGENIC("RADIOGENIC")

References _, Creature::add_effect(), add_msg(), Creature::add_msg_if_player(), addiction_level(), addiction_scaling(), ALCOHOL, body_part_name(), broken, broken_bone_mends, CIG, clamp(), dead_tired, effect_cig, effect_drunk, effect_mending, effect_sleep, g, Creature::get_all_body_parts(), Creature::get_effect(), get_fatigue(), get_healthy(), get_rad(), get_stored_kcal(), get_thirst(), getID(), Creature::has_effect(), has_trait(), is_limb_broken(), m_debug, m_good, max_stored_kcal(), mutation_value(), parched, Creature::remove_effect(), rest_quality(), roll_remainder(), Creature::set_part_hp_cur(), trait_RADIOGENIC, trait_REGEN_LIZ, very_thirsty, and worn_with_flag().

Referenced by update_body().

◆ metabolic_rate()

float Character::metabolic_rate ( ) const

Current metabolic rate due to traits, hunger, speed, etc.

Definition at line 614 of file consumption.cpp.

615{
616 return metabolic_rate_base();
617}

References metabolic_rate_base().

Referenced by calc_needs_rates().

◆ metabolic_rate_base()

float Character::metabolic_rate_base ( ) const

Stable base metabolic rate due to traits.

Definition at line 601 of file consumption.cpp.

602{
603 static const std::string hunger_rate_string( "PLAYER_HUNGER_RATE" );
604 static const std::string metabolism_modifier( "metabolism_modifier" );
605
606 float hunger_rate = get_option< float >( hunger_rate_string );
607 float mut_bonus = 1.0f + mutation_value( metabolism_modifier );
608 float with_mut = hunger_rate * mut_bonus;
609 float ench_bonus = bonus_from_enchantments( with_mut, enchant_vals::mod::METABOLISM );
610
611 return std::max( 0.0f, with_mut + ench_bonus );
612}

References bonus_from_enchantments(), enchant_vals::METABOLISM, and mutation_value().

Referenced by bmr(), and metabolic_rate().

◆ mod_base_age()

void Character::mod_base_age ( int  mod)

Definition at line 6750 of file character.cpp.

6751{
6752 init_age += mod;
6753}

References init_age.

Referenced by set_description().

◆ mod_base_height()

void Character::mod_base_height ( int  mod)

Definition at line 6779 of file character.cpp.

6780{
6781 init_height += mod;
6782}

References init_height.

Referenced by set_description().

◆ mod_dex_bonus()

void Character::mod_dex_bonus ( int  ndex)
virtual

◆ mod_fatigue()

◆ mod_healthy()

void Character::mod_healthy ( int  nhealthy)
virtual

Modifiers for health values exclusive to characters.

Definition at line 4234 of file character.cpp.

4235{
4236 float mut_rate = 1.0f;
4237 for( const trait_id &mut : get_mutations() ) {
4238 mut_rate *= mut.obj().healthy_rate;
4239 }
4240 healthy += nhealthy * mut_rate;
4241}

References get_mutations(), and healthy.

Referenced by iuse::adrenaline_injector(), mod_stat(), process_one_effect(), spell_effect::recover_energy(), and update_health().

◆ mod_healthy_mod()

void Character::mod_healthy_mod ( int  nhealthy_mod,
int  cap 
)
virtual

Definition at line 4246 of file character.cpp.

4247{
4248 // TODO: This really should be a full morale-like system, with per-effect caps
4249 // and durations. This version prevents any single effect from exceeding its
4250 // intended ceiling, but multiple effects will overlap instead of adding.
4251
4252 // Cap indicates how far the mod is allowed to shift in this direction.
4253 // It can have a different sign to the mod, e.g. for items that treat
4254 // extremely low health, but can't make you healthy.
4255 if( nhealthy_mod == 0 || cap == 0 ) {
4256 return;
4257 }
4258 int low_cap;
4259 int high_cap;
4260 if( nhealthy_mod < 0 ) {
4261 low_cap = cap;
4262 high_cap = 200;
4263 } else {
4264 low_cap = -200;
4265 high_cap = cap;
4266 }
4267
4268 // If we're already out-of-bounds, we don't need to do anything.
4269 if( ( healthy_mod <= low_cap && nhealthy_mod < 0 ) ||
4270 ( healthy_mod >= high_cap && nhealthy_mod > 0 ) ) {
4271 return;
4272 }
4273
4274 healthy_mod += nhealthy_mod;
4275
4276 // Since we already bailed out if we were out-of-bounds, we can
4277 // just clamp to the boundaries here.
4278 healthy_mod = std::min( healthy_mod, high_cap );
4279 healthy_mod = std::max( healthy_mod, low_cap );
4280}

References healthy_mod.

Referenced by addict_effect(), iuse::blech(), check_needs_extremes(), consume_effects(), hardcoded_effects(), modify_health(), iuse::mycus(), iuse::plantblech(), process_one_effect(), rooted(), suffer_from_bad_bionics(), suffer_from_other_mutations(), update_health(), and iuse::vaccine().

◆ mod_int_bonus()

void Character::mod_int_bonus ( int  nint)
virtual

◆ mod_max_power_level()

void Character::mod_max_power_level ( const units::energy npower_max)

Definition at line 1917 of file character.cpp.

1918{
1919 max_power_level += npower_max;
1920}

References max_power_level.

Referenced by activate_mutation(), add_bionic(), perform_uninstall(), and uninstall_bionic().

◆ mod_pain()

void Character::mod_pain ( int  npain)
overridevirtual

Modifies a pain value by player traits before passing it to Creature::mod_pain()

Reimplemented from Creature.

Definition at line 750 of file character.cpp.

751{
752 if( npain > 0 ) {
754 return;
755 }
756 // always increase pain gained by one from these bad mutations
757 if( has_trait( trait_MOREPAIN ) ) {
758 npain += std::max( 1, roll_remainder( npain * 0.25 ) );
759 } else if( has_trait( trait_MOREPAIN2 ) ) {
760 npain += std::max( 1, roll_remainder( npain * 0.5 ) );
761 } else if( has_trait( trait_MOREPAIN3 ) ) {
762 npain += std::max( 1, roll_remainder( npain * 1.0 ) );
763 }
764
765 if( npain > 1 ) {
766 // if it's 1 it'll just become 0, which is bad
768 npain = roll_remainder( npain * 0.5 );
769 } else if( has_trait( trait_PAINRESIST ) ) {
770 npain = roll_remainder( npain * 0.67 );
771 }
772 }
773 }
774 Creature::mod_pain( npain );
775}
static const efftype_id effect_narcosis("narcosis")
static const trait_id trait_MOREPAIN("MORE_PAIN")
static const trait_id trait_PAINRESIST_TROGLO("PAINRESIST_TROGLO")
static const trait_id trait_MOREPAIN2("MORE_PAIN2")
static const trait_id trait_PAINRESIST("PAINRESIST")
static const trait_id trait_MOREPAIN3("MORE_PAIN3")
virtual void mod_pain(int npain)
Definition: creature.cpp:1353

References effect_narcosis, Creature::has_effect(), has_trait(), Creature::mod_pain(), roll_remainder(), trait_MOREPAIN, trait_MOREPAIN2, trait_MOREPAIN3, trait_NOPAIN, trait_PAINRESIST, and trait_PAINRESIST_TROGLO.

Referenced by addict_effect(), iuse::antiparasitic(), apply_damage(), iexamine::autodoc(), iuse::blech(), iuse::blood_draw(), blood_magic(), burn_move_stamina(), activity_handlers::burrow_finish(), cauterize_actor::cauterize_effect(), debug_menu::character_edit_menu(), consume_effects(), eff_fun_bleed(), iuse::ehandcuffs(), game::find_or_make_stairs(), game::grabbed_furn_move(), game::grabbed_veh_move(), hardcoded_effects(), hurtall(), marloss_common(), game::mon_info_update(), iuse::mycus(), activity_handlers::pickaxe_finish(), map::player_in_field(), process_bionic(), process_one_effect(), sounds::process_sound_markers(), iuse::purify_iv(), iuse::purify_smart(), spell_effect::recover_energy(), regen(), suffer_from_bad_bionics(), suffer_from_chemimbalance(), suffer_from_radiation(), suffer_from_sunburn(), suffer_without_sleep(), try_reject_mutagen(), update_needs(), mutagen_actor::use(), mutagen_iv_actor::use(), and iuse::vaccine().

◆ mod_painkiller()

void Character::mod_painkiller ( int  npkill)

◆ mod_per_bonus()

void Character::mod_per_bonus ( int  nper)
virtual

◆ mod_power_level()

void Character::mod_power_level ( const units::energy npower)

Definition at line 1905 of file character.cpp.

1906{
1907 // Remaining capacity between current and maximum power levels we can make use of.
1908 const units::energy remaining_capacity = get_max_power_level() - get_power_level();
1909 // We can't add more than remaining capacity, so get the minimum of the two
1910 const units::energy minned_npower = std::min( npower, remaining_capacity );
1911 // new candidate power level
1912 const units::energy new_power = get_power_level() + minned_npower;
1913 // set new power level while prevending it from going negative
1914 set_power_level( std::max( 0_kJ, new_power ) );
1915}

References get_max_power_level(), get_power_level(), and set_power_level().

Referenced by activate_bionic(), activate_mutation(), item::ammo_consume(), burn_fuel(), npc::check_or_use_weapon_cbm(), deactivate_bionic(), npc::discharge_cbm_weapon(), do_skill_rust(), iuse::ehandcuffs(), explosion_handler::emp_blast(), feed_furnace_with(), aim_activity_actor::finish(), iexamine::fireplace(), hack_attempt(), melee_special_effects(), modify_morale(), game::monmove(), on_hit(), game::on_move_effects(), passive_power_gen(), game::phasing_move(), process_bionic(), process_turn(), npc::recharge_cbm(), spell_effect::recover_energy(), mattack::riotbot(), activity_handlers::spellcasting_finish(), suffer_from_asthma(), suffer_from_bad_bionics(), suffer_from_radiation(), suffer_while_underwater(), try_start_hacking(), character_funcs::try_uncanny_dodge(), update_stamina(), use_charges(), and use_fire().

◆ mod_rad()

void Character::mod_rad ( int  mod)

Definition at line 7040 of file character.cpp.

7041{
7042 if( has_trait_flag( "NO_RADIATION" ) ) {
7043 return;
7044 }
7045 set_rad( std::max( 0, get_rad() + mod ) );
7046}

References get_rad(), has_trait_flag(), and set_rad().

Referenced by activate_bionic(), irradiate(), game::process_artifact(), process_one_effect(), regen(), and suffer_from_radiation().

◆ mod_skill_level()

void Character::mod_skill_level ( const skill_id ident,
int  delta 
)

Definition at line 3332 of file character.cpp.

3333{
3334 _skills->mod_skill_level( ident, delta );
3335}

References _skills.

Referenced by avatar::create(), npc::randomize(), and set_skills().

◆ mod_sleep_deprivation()

void Character::mod_sleep_deprivation ( int  nsleep_deprivation)
virtual

Definition at line 4423 of file character.cpp.

4424{
4425 set_sleep_deprivation( sleep_deprivation + nsleep_deprivation );
4426}

References set_sleep_deprivation(), and sleep_deprivation.

Referenced by update_needs().

◆ mod_stamina()

◆ mod_stat()

void Character::mod_stat ( const std::string &  stat,
float  modifier 
)
overridevirtual

Reimplemented from Creature.

Definition at line 532 of file character.cpp.

533{
534 if( stat == "str" ) {
535 mod_str_bonus( modifier );
536 } else if( stat == "dex" ) {
537 mod_dex_bonus( modifier );
538 } else if( stat == "per" ) {
539 mod_per_bonus( modifier );
540 } else if( stat == "int" ) {
541 mod_int_bonus( modifier );
542 } else if( stat == "healthy" ) {
543 mod_healthy( modifier );
544 } else if( stat == "kcal" ) {
545 mod_stored_kcal( modifier );
546 } else if( stat == "hunger" ) {
547 mod_stored_kcal( -10 * modifier );
548 } else if( stat == "thirst" ) {
549 mod_thirst( modifier );
550 } else if( stat == "fatigue" ) {
551 mod_fatigue( modifier );
552 } else if( stat == "oxygen" ) {
553 oxygen += modifier;
554 } else if( stat == "stamina" ) {
555 mod_stamina( modifier );
556 } else {
557 Creature::mod_stat( stat, modifier );
558 }
559}
virtual void mod_healthy(int nhealthy)
Modifiers for health values exclusive to characters.
Definition: character.cpp:4234
virtual void mod_stat(const std::string &stat, float modifier)
Definition: creature.cpp:1701

References mod_dex_bonus(), mod_fatigue(), mod_healthy(), mod_int_bonus(), mod_per_bonus(), mod_stamina(), Creature::mod_stat(), mod_stored_kcal(), mod_str_bonus(), mod_thirst(), and oxygen.

Referenced by apply_skill_boost(), shout(), and consume_drug_iuse::use().

◆ mod_stim()

void Character::mod_stim ( int  mod)

◆ mod_stored_kcal()

◆ mod_stored_nutr()

void Character::mod_stored_nutr ( int  nnutr)
virtual

◆ mod_str_bonus()

void Character::mod_str_bonus ( int  nstr)
virtual

◆ mod_thirst()

◆ modify_addiction()

void Character::modify_addiction ( const islot_comestible comest)

Used to apply addiction modifications from food and medication.

Definition at line 1051 of file consumption.cpp.

1052{
1053 add_addiction( comest.add, comest.addict );
1054 if( addiction_craving( comest.add ) != MORALE_NULL ) {
1055 rem_morale( addiction_craving( comest.add ) );
1056 }
1057}
morale_type addiction_craving(add_type const cur)
Definition: addiction.cpp:307
void add_addiction(add_type type, int strength)
Adds an addiction to the player.
Definition: suffer.cpp:1894
add_type add
effects of addiction
Definition: itype.h:142
int addict
addiction potential
Definition: itype.h:139

References islot_comestible::add, add_addiction(), islot_comestible::addict, addiction_craving(), MORALE_NULL, and rem_morale().

Referenced by consume_effects(), and consume_med().

◆ modify_fatigue()

void Character::modify_fatigue ( const islot_comestible comest)

Used to apply fatigue modifications from food and medication.

Definition at line 1041 of file consumption.cpp.

1042{
1043 mod_fatigue( -comest.fatigue_mod );
1044}
int fatigue_mod
fatigue altering effect
Definition: itype.h:148

References islot_comestible::fatigue_mod, and mod_fatigue().

Referenced by consume_effects(), and consume_med().

◆ modify_health()

void Character::modify_health ( const islot_comestible comest)

Used to apply health modifications from food and medication.

Definition at line 998 of file consumption.cpp.

999{
1000 const int effective_health = comest.healthy;
1001 // Effectively no cap on health modifiers from food and meds
1002 const int health_cap = 200;
1003 mod_healthy_mod( effective_health, effective_health >= 0 ? health_cap : -health_cap );
1004}
int healthy
TODO: add documentation.
Definition: itype.h:157

References islot_comestible::healthy, and mod_healthy_mod().

Referenced by consume_effects(), and consume_med().

◆ modify_morale()

void Character::modify_morale ( item food,
int  nutr = 0 
)

Used to apply morale modifications from food and medication.

Definition at line 1059 of file consumption.cpp.

1060{
1061 time_duration morale_time = 2_hours;
1062 if( food.has_flag( flag_EATEN_HOT ) ) {
1063 auto heater = find_food_heater( *this, crafting_inventory(),
1064 get_map().has_nearby_fire( pos(), PICKUP_RANGE ) );
1065 if( heater && heater->consume( *this ) ) {
1067 _( "You heat up your %1$s using the %2$s." ),
1068 _( "<npcname> heats up their %1$s using the %2$s." ),
1069 food.tname(), heater->it.tname() );
1070 morale_time = 3_hours;
1071 int clamped_nutr = std::max( 5, std::min( 20, nutr / 10 ) );
1072 add_morale( MORALE_FOOD_HOT, clamped_nutr, 20, morale_time, morale_time / 2 );
1073 }
1074 }
1075
1076 std::pair<int, int> fun = fun_for( food );
1077 if( fun.first < 0 ) {
1079 get_power_level() > units::from_kilojoule( -fun.first ) ) {
1080 mod_power_level( units::from_kilojoule( std::min( 0, fun_for( food ).first ) ) );
1081 } else {
1082 add_morale( MORALE_FOOD_BAD, fun.first, fun.second, morale_time, morale_time / 2, false,
1083 food.type );
1084 }
1085 } else if( fun.first > 0 ) {
1086 add_morale( MORALE_FOOD_GOOD, fun.first, fun.second, morale_time, morale_time / 2, false,
1087 food.type );
1088 }
1089
1090 if( food.has_flag( flag_HIDDEN_HALLU ) ) {
1091 if( has_trait( trait_SPIRITUAL ) ) {
1092 add_morale( MORALE_FOOD_GOOD, 36, 72, 2_hours, 1_hours, false );
1093 } else {
1094 add_morale( MORALE_FOOD_GOOD, 18, 36, 1_hours, 30_minutes, false );
1095 }
1096 }
1097
1098 if( food.has_flag( flag_CANNIBALISM ) ) {
1099 const bool cannibal = has_trait( trait_CANNIBAL );
1100 const bool psycho = has_trait( trait_PSYCHOPATH );
1101 const bool sapiovore = has_trait( trait_SAPIOVORE );
1102 if( cannibal ) {
1103 add_msg_if_player( m_good, _( "You indulge your shameful hunger." ) );
1104 add_morale( MORALE_CANNIBAL, 20, 200 );
1105 } else if( psycho || sapiovore ) {
1106 // Nothing - doesn't care enough to print a message
1107 } else {
1108 add_msg_if_player( m_bad, _( "You feel horrible for eating a person." ) );
1109 add_morale( MORALE_CANNIBAL, -60, -400, 60_minutes, 30_minutes );
1110 }
1111 }
1112
1113 // Allergy check for food that is ingested (not gum)
1114 if( !food.has_flag( "NO_INGEST" ) ) {
1115 const auto allergy = allergy_type( food );
1116 if( allergy != MORALE_NULL ) {
1117 add_msg_if_player( m_bad, _( "Yuck! How can anybody eat this stuff?" ) );
1118 add_morale( allergy, -75, -400, 30_minutes, 24_minutes );
1119 }
1120 if( food.has_flag( flag_ALLERGEN_JUNK ) ) {
1121 if( has_trait( trait_PROJUNK ) ) {
1122 add_msg_if_player( m_good, _( "Mmm, junk food." ) );
1123 add_morale( MORALE_SWEETTOOTH, 5, 30, 30_minutes, 24_minutes );
1124 }
1125 if( has_trait( trait_PROJUNK2 ) ) {
1126 if( !one_in( 100 ) ) {
1127 add_msg_if_player( m_good, _( "When life's got you down, there's always sugar." ) );
1128 } else {
1129 add_msg_if_player( m_good, _( "They may do what they must… you've already won." ) );
1130 }
1131 add_morale( MORALE_SWEETTOOTH, 10, 50, 1_hours, 50_minutes );
1132 }
1133 // Carnivores CAN eat junk food, but they won't like it much.
1134 // Pizza-scraping happens in consume_effects.
1136 add_msg_if_player( m_bad, _( "Your stomach begins gurgling and you feel bloated and ill." ) );
1137 add_morale( MORALE_NO_DIGEST, -25, -125, 30_minutes, 24_minutes );
1138 }
1139 }
1140 }
1141 const bool chew = food.get_comestible()->comesttype == comesttype_FOOD ||
1143 if( !food.rotten() && chew && has_trait( trait_SAPROPHAGE ) ) {
1144 // It's OK to *drink* things that haven't rotted. Alternative is to ban water. D:
1145 add_msg_if_player( m_bad, _( "Your stomach begins gurgling and you feel bloated and ill." ) );
1146 add_morale( MORALE_NO_DIGEST, -75, -400, 30_minutes, 24_minutes );
1147 }
1148 if( food.has_flag( flag_URSINE_HONEY ) && ( !crossed_threshold() ||
1150 mutation_category_level["URSINE"] > 40 ) {
1151 // Need at least 5 bear mutations for effect to show, to filter out mutations in common with other categories
1152 int honey_fun = has_trait( trait_THRESH_URSINE ) ?
1153 std::min( mutation_category_level["URSINE"] / 8, 20 ) :
1154 mutation_category_level["URSINE"] / 12;
1155 if( honey_fun < 10 ) {
1156 add_msg_if_player( m_good, _( "You find the sweet taste of honey surprisingly palatable." ) );
1157 } else {
1158 add_msg_if_player( m_good, _( "You feast upon the sweet honey." ) );
1159 }
1160 add_morale( MORALE_HONEY, honey_fun, 100 );
1161 }
1162}
morale_type allergy_type(const item &food) const
Returns allergy type or MORALE_NULL if not allergic for this character.
std::pair< int, int > fun_for(const item &comest) const
Handles the enjoyability value for a comestible.
static const bionic_id bio_taste_blocker("bio_taste_blocker")
static cata::optional< prepared_item_consumption > find_food_heater(Character &c, const inventory &inv, bool has_fire)
static const trait_id trait_THRESH_URSINE("THRESH_URSINE")
static const std::string flag_URSINE_HONEY("URSINE_HONEY")
static const std::string flag_CANNIBALISM("CANNIBALISM")
static const trait_id trait_SAPIOVORE("SAPIOVORE")
static const trait_id trait_PSYCHOPATH("PSYCHOPATH")
static const trait_id trait_PROJUNK("PROJUNK")
static const trait_id trait_SPIRITUAL("SPIRITUAL")
static const std::string flag_EATEN_HOT("EATEN_HOT")
static const trait_id trait_CANNIBAL("CANNIBAL")
const morale_type MORALE_HONEY("morale_honey")
const morale_type MORALE_SWEETTOOTH("morale_sweettooth")
const morale_type MORALE_NO_DIGEST("morale_no_digest")
const morale_type MORALE_FOOD_HOT("morale_food_hot")
const morale_type MORALE_FOOD_GOOD("morale_food_good")
const morale_type MORALE_CANNIBAL("morale_cannibal")
const morale_type MORALE_FOOD_BAD("morale_food_bad")

References _, add_morale(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), allergy, allergy_type(), bio_taste_blocker, iuse::chew(), comesttype_FOOD(), crafting_inventory(), crossed_threshold(), find_food_heater(), flag_ALLERGEN_JUNK(), flag_CANNIBALISM(), flag_CARNIVORE_OK(), flag_EATEN_HOT(), flag_HIDDEN_HALLU(), flag_URSINE_HONEY(), flag_USE_EAT_VERB(), units::from_kilojoule(), fun_for(), item::get_comestible(), get_map(), get_power_level(), has_active_bionic(), item::has_flag(), has_trait(), m_bad, m_good, mod_power_level(), MORALE_CANNIBAL, MORALE_FOOD_BAD, MORALE_FOOD_GOOD, MORALE_FOOD_HOT, MORALE_HONEY, MORALE_NO_DIGEST, MORALE_NULL, MORALE_SWEETTOOTH, mutation_category_level, one_in(), PICKUP_RANGE, pos(), item::rotten(), item::tname(), trait_CANNIBAL, trait_CARNIVORE, trait_PROJUNK, trait_PROJUNK2, trait_PSYCHOPATH, trait_SAPIOVORE, trait_SAPROPHAGE, trait_SPIRITUAL, trait_THRESH_URSINE, and item::type.

Referenced by consume_effects(), and consume_med().

◆ modify_radiation()

void Character::modify_radiation ( const islot_comestible comest)

Used to apply radiation from food and medication.

Definition at line 1046 of file consumption.cpp.

1047{
1048 irradiate( comest.radiation );
1049}
int radiation
Amount of radiation you get from this comestible.
Definition: itype.h:163

References irradiate(), and islot_comestible::radiation.

Referenced by consume_effects(), and consume_med().

◆ modify_stimulation()

void Character::modify_stimulation ( const islot_comestible comest)

Used to apply stimulation modifications from food and medication.

Definition at line 1006 of file consumption.cpp.

1007{
1008 const int current_stim = get_stim();
1009 if( comest.stim != 0 &&
1010 ( std::abs( current_stim ) < ( std::abs( comest.stim ) * 3 ) ||
1011 sgn( current_stim ) != sgn( comest.stim ) ) ) {
1012 if( comest.stim < 0 ) {
1013 set_stim( std::max( comest.stim * 3, current_stim + comest.stim ) );
1014 } else {
1015 set_stim( std::min( comest.stim * 3, current_stim + comest.stim ) );
1016 }
1017 }
1018 if( has_trait( trait_STIMBOOST ) && ( current_stim > 30 ) &&
1019 ( ( comest.add == add_type::CAFFEINE ) || ( comest.add == add_type::SPEED ) ||
1020 ( comest.add == add_type::COKE ) || ( comest.add == add_type::CRACK ) ) ) {
1021 int hallu_duration = ( current_stim - comest.stim < 30 ) ? current_stim - 30 : comest.stim;
1022 add_effect( effect_visuals, hallu_duration * 30_minutes );
1023 std::vector<std::string> stimboost_msg{ _( "The shadows are getting ever closer." ),
1024 _( "You have a bad feeling about this." ),
1025 _( "A powerful sense of dread comes over you." ),
1026 _( "Your skin starts crawling." ),
1027 _( "They're coming to get you." ),
1028 _( "This might've been a bad idea…" ),
1029 _( "You've really done it this time, haven't you?" ),
1030 _( "You have to stay vigilant. They're always watching…" ),
1031 _( "mistake mistake mistake mistake mistake" ),
1032 _( "Just gotta stay calm, and you'll make it through this." ),
1033 _( "You're starting to feel very jumpy." ),
1034 _( "Something is twitching at the edge of your vision." ),
1035 _( "They know what you've done…" ),
1036 _( "You're feeling even more paranoid than usual." ) };
1037 add_msg_if_player( m_bad, random_entry_ref( stimboost_msg ) );
1038 }
1039}
static const efftype_id effect_visuals("visuals")
static const trait_id trait_STIMBOOST("STIMBOOST")
constexpr int sgn(const T x)
Definition: enums.h:8
std::enable_if<!is_std_array< C >::value, constV & >::type random_entry_ref(const C &container)
Same as above, but with a statically allocated default value (using the default constructor).
Definition: rng.h:149
int stim
stimulant effect
Definition: itype.h:145

References _, islot_comestible::add, Creature::add_effect(), Creature::add_msg_if_player(), CAFFEINE, COKE, CRACK, effect_visuals, get_stim(), has_trait(), m_bad, random_entry_ref(), set_stim(), sgn(), SPEED, islot_comestible::stim, and trait_STIMBOOST.

Referenced by consume_effects(), and consume_med().

◆ mount_creature()

void Character::mount_creature ( monster z)

Definition at line 954 of file character.cpp.

955{
956 tripoint pnt = z.pos();
957 shared_ptr_fast<monster> mons = g->shared_from( z );
958 if( mons == nullptr ) {
959 add_msg( m_debug, "mount_creature(): monster not found in critter_tracker" );
960 return;
961 }
962 add_effect( effect_riding, 1_turns, num_bp );
963 z.add_effect( effect_ridden, 1_turns, num_bp );
964 if( z.has_effect( effect_tied ) ) {
966 if( z.tied_item ) {
967 i_add( *z.tied_item );
968 z.tied_item.reset();
969 }
970 }
972 if( z.has_effect( effect_harnessed ) ) {
974 add_msg_if_player( m_info, _( "You remove the %s's harness." ), z.get_name() );
975 }
976 mounted_creature = mons;
977 mons->mounted_player = this;
978 if( is_avatar() ) {
979 if( g->u.is_hauling() ) {
980 g->u.stop_hauling();
981 }
982 if( g->u.get_grab_type() != OBJECT_NONE ) {
983 add_msg( m_warning, _( "You let go of the grabbed object." ) );
984 g->u.grab( OBJECT_NONE );
985 }
986 g->place_player( pnt );
987 } else {
988 npc &guy = dynamic_cast<npc &>( *this );
989 guy.setpos( pnt );
990 }
991 z.facing = facing;
992 add_msg_if_player( m_good, _( "You climb on the %s." ), z.get_name() );
993 if( z.has_flag( MF_RIDEABLE_MECH ) ) {
994 if( !z.type->mech_weapon.is_empty() ) {
995 item mechwep = item( z.type->mech_weapon );
996 wield( mechwep );
997 }
998 add_msg_if_player( m_good, _( "You hear your %s whir to life." ), z.get_name() );
999 }
1000 // some rideable mechs have night-vision
1002 mod_moves( -100 );
1003}
static const efftype_id effect_tied("tied")
static const efftype_id effect_harnessed("harnessed")
FacingDirection facing
return the direction the creature is facing, for sdl horizontal flip
Definition: creature.h:135
cata::value_ptr< item > tied_item
Definition: monster.h:460
std::string get_name() const override
Definition: monster.cpp:488
void setpos(const tripoint &pos) override
Note: this places NPC on a given position in CURRENT MAP coordinates.
Definition: npc.cpp:688
std::shared_ptr< T > shared_ptr_fast
Definition: memory_fast.h:16

References _, Creature::add_effect(), monster::add_effect(), add_msg(), Creature::add_msg_if_player(), effect_harnessed, effect_ridden, effect_riding, effect_tied, Creature::facing, g, monster::get_name(), getID(), Creature::has_effect(), monster::has_flag(), i_add(), Creature::is_avatar(), string_id< T >::is_empty(), m_debug, m_good, m_info, m_warning, mtype::mech_weapon, MF_RIDEABLE_MECH, Creature::mod_moves(), mounted_creature, monster::mounted_player_id, num_bp, OBJECT_NONE, monster::pos(), recalc_sight_limits(), Creature::remove_effect(), npc::setpos(), monster::tied_item, monster::type, and wield().

Referenced by activity_handlers::find_mount_do_turn(), and monexamine::mount_pet().

◆ move_effects()

bool Character::move_effects ( bool  attacking)
overridevirtual

Processes effects which may prevent the Character from moving (bear traps, crushed, etc.).

Returns false if movement is stopped.

Strength increases chance to escape pit Dexterity increases chance to escape pit, slightly

Implements Creature.

Definition at line 1456 of file character.cpp.

1457{
1458 if( has_effect( effect_downed ) ) {
1459 try_remove_downed( *this );
1460 return false;
1461 }
1462 if( has_effect( effect_webbed ) ) {
1463 try_remove_webs( *this );
1464 return false;
1465 }
1466 if( has_effect( effect_lightsnare ) ) {
1467 try_remove_lightsnare( *this );
1468 return false;
1469
1470 }
1471 if( has_effect( effect_heavysnare ) ) {
1472 try_remove_heavysnare( *this );
1473 return false;
1474 }
1475 if( has_effect( effect_beartrap ) ) {
1476 try_remove_bear_trap( *this );
1477 return false;
1478 }
1479 if( has_effect( effect_crushed ) ) {
1480 try_remove_crushed( *this );
1481 return false;
1482 }
1483 // Below this point are things that allow for movement if they succeed
1484
1485 // Currently we only have one thing that forces movement if you succeed, should we get more
1486 // than this will need to be reworked to only have success effects if /all/ checks succeed
1487 if( has_effect( effect_in_pit ) ) {
1488 /** @EFFECT_STR increases chance to escape pit */
1489
1490 /** @EFFECT_DEX increases chance to escape pit, slightly */
1491 if( rng( 0, 40 ) > get_str() + get_dex() / 2 ) {
1492 add_msg_if_player( m_bad, _( "You try to escape the pit, but slip back in." ) );
1493 return false;
1494 } else {
1495 add_msg_player_or_npc( m_good, _( "You escape the pit!" ),
1496 _( "<npcname> escapes the pit!" ) );
1498 }
1499 }
1500 if( has_effect( effect_grabbed ) && !attacking && !try_remove_grab( *this ) ) {
1501 // NOLINTNEXTLINE(readability-simplify-boolean-expr)
1502 return false;
1503 }
1504 return true;
1505}
static void try_remove_lightsnare(Character &c)
Definition: character.cpp:1306
static void try_remove_crushed(Character &c)
Definition: character.cpp:1366
static const efftype_id effect_crushed("crushed")
static void try_remove_heavysnare(Character &c)
Definition: character.cpp:1335
static void try_remove_bear_trap(Character &c)
Definition: character.cpp:1270
static void try_remove_webs(Character &c)
Definition: character.cpp:1436
static bool try_remove_grab(Character &c)
Definition: character.cpp:1380
static const efftype_id effect_webbed("webbed")
static const efftype_id effect_in_pit("in_pit")
static void try_remove_downed(Character &c)
Definition: character.cpp:1255

References _, Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), effect_beartrap, effect_crushed, effect_downed, effect_grabbed, effect_heavysnare, effect_in_pit, effect_lightsnare, effect_webbed, get_dex(), get_str(), Creature::has_effect(), m_bad, m_good, Creature::remove_effect(), rng(), try_remove_bear_trap(), try_remove_crushed(), try_remove_downed(), try_remove_grab(), try_remove_heavysnare(), try_remove_lightsnare(), and try_remove_webs().

Referenced by avatar_action::move(), npc::move_to(), and game::vertical_move().

◆ movement_mode_is()

bool Character::movement_mode_is ( character_movemode  mode) const

Check against the character's current movement mode.

Definition at line 1540 of file character.cpp.

1541{
1542 return move_mode == mode;
1543}

References move_mode.

Referenced by map::build_vision_transparency_cache(), avatar::cycle_move_mode(), draw_health_classic(), avatar_action::move(), move_mode_color(), move_mode_string(), game::on_move_effects(), Creature::sees(), game::vertical_move(), and game::walk_move().

◆ mut_cbm_encumb()

void Character::mut_cbm_encumb ( char_encumbrance_data vals) const
protected

Applies encumbrance from mutations and bionics only.

Definition at line 4009 of file character.cpp.

4010{
4011
4012 for( const bionic_id &bid : get_bionics() ) {
4013 for( const std::pair<const bodypart_str_id, int> &element : bid->encumbrance ) {
4014 vals.elems[element.first->token].encumbrance += element.second;
4015 }
4016 }
4017
4019 for( auto &val : vals.elems ) {
4020 val.encumbrance += 3; // Slight encumbrance to all parts except eyes
4021 }
4022 vals.elems[bp_eyes].encumbrance -= 3;
4023 }
4024
4025 // Lower penalty for bps covered only by XL armor
4026 const auto oversize = exclusive_flag_coverage( flag_OVERSIZE );
4027 for( const trait_id &mut : get_mutations() ) {
4028 apply_mut_encumbrance( vals, mut, oversize );
4029 }
4030}
static const bionic_id bio_shock_absorber("bio_shock_absorber")
static void apply_mut_encumbrance(char_encumbrance_data &vals, const trait_id &mut, const body_part_set &oversize)
Definition: character.cpp:3994

References apply_mut_encumbrance(), bio_shock_absorber, bp_eyes, char_encumbrance_data::elems, exclusive_flag_coverage(), flag_OVERSIZE(), get_bionics(), get_mutations(), and has_active_bionic().

Referenced by calc_encumbrance().

◆ mutate()

void Character::mutate ( )

Picks a random valid mutation and gives it to the Character, possibly removing/changing others along the way.

Definition at line 835 of file mutation.cpp.

836{
837 if( get_option<bool>( "BALANCED_MUTATIONS" ) ) {
839 if( !mutagen ) {
840 return;
841 }
842 float mut_power = to_turns<float>( mutagen.get_duration() ) / to_turns<float>
843 ( mutagen.get_int_dur_factor() );
844 add_msg_if_player( m_debug, "Mutation accumulation: %.1f", mut_power );
845 while( mut_power > 1 || roll_remainder( mut_power ) > 0 ) {
846 std::map<trait_id, float> chances = mutation_chances();
847
848 weighted_float_list<trait_id> mutation_picker;
849 for( const auto &p : chances ) {
850 mutation_picker.add( p.first, p.second );
851 }
852
853 for( int tries = 0; tries < 3; tries++ ) {
854 const trait_id *selected = mutation_picker.pick();
855 if( selected == nullptr ) {
856 continue;
857 }
858 add_msg_if_player( m_debug, "Selected mutation %s", selected->obj().name().c_str() );
859 if( has_trait( *selected ) ) {
860 remove_mutation( *selected );
861 break;
862 } else {
863 mutate_towards( *selected );
864 break;
865 }
866 }
867
868 mutagen.mod_duration( -mutagen.get_int_dur_factor() );
869 mut_power -= 1.0f;
870 }
871 } else {
872 old_mutate();
874 }
875}
void remove_mutation(const trait_id &mut, bool silent=false)
Removes a mutation, downgrading to the previous level if possible.
Definition: mutation.cpp:1328
bool mutate_towards(std::vector< trait_id > muts, int num_tries=INT_MAX)
Mutates toward one of the given mutations, upgrading or removing conflicts if necessary.
Definition: mutation.cpp:1087
std::map< trait_id, float > mutation_chances() const
Calculate percentage chances for mutations.
Definition: mutation.cpp:742
void old_mutate()
Definition: mutation.cpp:877
time_duration get_int_dur_factor() const
Returns the number of turns it takes for the intensity to fall by 1 or 0 if intensity isn't based on ...
Definition: effect.cpp:1207
static const efftype_id effect_accumulated_mutagen("accumulated_mutagen")
T * add(const T &obj, const W &weight)
This will add a new object to the weighted list.
Definition: weighted_list.h:33
const T * pick(unsigned int randi) const
This will return a pointer to an object from the list randomly selected and biased by weight.
Definition: weighted_list.h:94

References weighted_list< W, T >::add(), Creature::add_msg_if_player(), effect_accumulated_mutagen, effect::get_duration(), Creature::get_effect(), effect::get_int_dur_factor(), has_trait(), m_debug, effect::mod_duration(), mutate_towards(), mutation_chances(), mutation_branch::name(), old_mutate(), weighted_list< W, T >::pick(), Creature::remove_effect(), remove_mutation(), and roll_remainder().

Referenced by iuse::artifact(), eff_fun_mutating(), hardcoded_effects(), marloss_common(), spell_effect::mutate(), mutate_category(), iuse::mycus(), mattack::science(), iuse::sewage(), suffer_from_artifacts(), suffer_from_other_mutations(), and suffer_from_radiation().

◆ mutate_category()

void Character::mutate_category ( const std::string &  mut_cat)

Picks a random valid mutation in a category and mutate_towards() it.

Definition at line 1034 of file mutation.cpp.

1035{
1036 // Hacky ID comparison is better than separate hardcoded branch used before
1037 // TODO: Turn it into the null id
1038 if( cat == "ANY" ) {
1039 mutate();
1040 return;
1041 }
1042
1043 bool force_bad = one_in( 3 ) && !get_option<bool>( "BALANCED_MUTATIONS" );
1044 bool force_good = false;
1045 if( has_trait( trait_ROBUST ) && force_bad ) {
1046 // Robust Genetics gives you a 33% chance for a good mutation,
1047 // instead of the 33% chance of a bad one.
1048 force_bad = false;
1049 force_good = true;
1050 }
1051 if( has_trait( trait_CHAOTIC_BAD ) ) {
1052 force_bad = true;
1053 force_good = false;
1054 }
1055
1056 // Pull the category's list for valid mutations
1057 std::vector<trait_id> valid = mutations_category[cat];
1058
1059 // Remove anything we already have, that we have a child of, or that
1060 // goes against our intention of a good/bad mutation
1061 for( size_t i = 0; i < valid.size(); i++ ) {
1062 if( !mutation_ok( valid[i], force_good, force_bad ) ) {
1063 valid.erase( valid.begin() + i );
1064 i--;
1065 }
1066 }
1067
1068 mutate_towards( valid, 2 );
1069}
bool mutation_ok(const trait_id &mutation, bool force_good, bool force_bad) const
Returns true if the player doesn't have the mutation or a conflicting one and it complies with the fo...
Definition: mutation.cpp:629
static const trait_id trait_CHAOTIC_BAD("CHAOTIC_BAD")
static const trait_id trait_ROBUST("ROBUST")
std::map< std::string, std::vector< trait_id > > mutations_category

References has_trait(), mutate(), mutate_towards(), mutation_ok(), mutations_category, one_in(), trait_CHAOTIC_BAD, and trait_ROBUST.

Referenced by eff_fun_rat(), hardcoded_effects(), spell_effect::mutate(), iuse::mycus(), npc::randomize(), mutagen_actor::use(), and mutagen_iv_actor::use().

◆ mutate_towards() [1/2]

bool Character::mutate_towards ( const trait_id mut)

Mutates toward the entered mutation, upgrading or removing conflicts if necessary.

Definition at line 1103 of file mutation.cpp.

1104{
1105 if( has_child_flag( mut ) ) {
1106 remove_child_flag( mut );
1107 return true;
1108 }
1109 const mutation_branch &mdata = mut.obj();
1110
1111 bool has_prereqs = false;
1112 bool prereq1 = false;
1113 bool prereq2 = false;
1114 std::vector<trait_id> canceltrait;
1115 std::vector<trait_id> prereq = mdata.prereqs;
1116 std::vector<trait_id> prereqs2 = mdata.prereqs2;
1117 std::vector<trait_id> cancel = mdata.cancels;
1118 std::vector<trait_id> same_type = get_mutations_in_types( mdata.types );
1119 std::vector<trait_id> all_prereqs = get_all_mutation_prereqs( mut );
1120
1121 // Check mutations of the same type - except for the ones we might need for pre-reqs
1122 for( const auto &consider : same_type ) {
1123 if( std::find( all_prereqs.begin(), all_prereqs.end(), consider ) == all_prereqs.end() ) {
1124 cancel.push_back( consider );
1125 }
1126 }
1127
1128 for( size_t i = 0; i < cancel.size(); i++ ) {
1129 if( !has_trait( cancel[i] ) ) {
1130 cancel.erase( cancel.begin() + i );
1131 i--;
1132 } else if( has_base_trait( cancel[i] ) ) {
1133 //If we have the trait, but it's a base trait, don't allow it to be removed normally
1134 canceltrait.push_back( cancel[i] );
1135 cancel.erase( cancel.begin() + i );
1136 i--;
1137 }
1138 }
1139
1140 for( size_t i = 0; i < cancel.size(); i++ ) {
1141 if( !cancel.empty() ) {
1142 trait_id removed = cancel[i];
1143 remove_mutation( removed );
1144 cancel.erase( cancel.begin() + i );
1145 i--;
1146 // This checks for cases where one trait knocks out several others
1147 // Probably a better way, but gets it Fixed Now--KA101
1148 return mutate_towards( mut );
1149 }
1150 }
1151
1152 for( size_t i = 0; ( !prereq1 ) && i < prereq.size(); i++ ) {
1153 if( has_trait( prereq[i] ) ) {
1154 prereq1 = true;
1155 }
1156 }
1157
1158 for( size_t i = 0; ( !prereq2 ) && i < prereqs2.size(); i++ ) {
1159 if( has_trait( prereqs2[i] ) ) {
1160 prereq2 = true;
1161 }
1162 }
1163
1164 if( prereq1 && prereq2 ) {
1165 has_prereqs = true;
1166 }
1167
1168 if( !has_prereqs && ( !prereq.empty() || !prereqs2.empty() ) ) {
1169 if( !prereq1 && !prereq.empty() ) {
1170 return mutate_towards( prereq );
1171 } else if( !prereq2 && !prereqs2.empty() ) {
1172 return mutate_towards( prereqs2 );
1173 }
1174 }
1175
1176 // Check for threshold mutation, if needed
1177 bool threshold = mdata.threshold;
1178 bool profession = mdata.profession;
1179 bool has_threshreq = false;
1180 std::vector<trait_id> threshreq = mdata.threshreq;
1181
1182 // It shouldn't pick a Threshold anyway--they're supposed to be non-Valid
1183 // and aren't categorized. This can happen if someone makes a threshold mutation into a prerequisite.
1184 if( threshold ) {
1185 add_msg_if_player( _( "You feel something straining deep inside you, yearning to be free…" ) );
1186 return false;
1187 }
1188 if( profession ) {
1189 // Profession picks fail silently
1190 return false;
1191 }
1192
1193 for( size_t i = 0; !has_threshreq && i < threshreq.size(); i++ ) {
1194 if( has_trait( threshreq[i] ) ) {
1195 has_threshreq = true;
1196 }
1197 }
1198
1199 // No crossing The Threshold by simply not having it
1200 if( !has_threshreq && !threshreq.empty() ) {
1201 add_msg_if_player( _( "You feel something straining deep inside you, yearning to be free…" ) );
1202 return false;
1203 }
1204
1205 // Check if one of the prerequisites that we have TURNS INTO this one
1206 trait_id replacing = trait_id::NULL_ID();
1207 prereq = mdata.prereqs; // Reset it
1208 for( auto &elem : prereq ) {
1209 if( has_trait( elem ) ) {
1210 const trait_id &pre = elem;
1211 const auto &p = pre.obj();
1212 for( size_t j = 0; !replacing && j < p.replacements.size(); j++ ) {
1213 if( p.replacements[j] == mut ) {
1214 replacing = pre;
1215 }
1216 }
1217 }
1218 }
1219
1220 // Loop through again for prereqs2
1221 trait_id replacing2 = trait_id::NULL_ID();
1222 prereq = mdata.prereqs2; // Reset it
1223 for( auto &elem : prereq ) {
1224 if( has_trait( elem ) ) {
1225 const trait_id &pre2 = elem;
1226 const auto &p = pre2.obj();
1227 for( size_t j = 0; !replacing2 && j < p.replacements.size(); j++ ) {
1228 if( p.replacements[j] == mut ) {
1229 replacing2 = pre2;
1230 }
1231 }
1232 }
1233 }
1234
1235 bool mutation_replaced = false;
1236
1237 game_message_type rating;
1238
1239 if( replacing ) {
1240 const auto &replace_mdata = replacing.obj();
1241 if( mdata.mixed_effect || replace_mdata.mixed_effect ) {
1242 rating = m_mixed;
1243 } else if( replace_mdata.points - mdata.points < 0 ) {
1244 rating = m_good;
1245 } else if( mdata.points - replace_mdata.points < 0 ) {
1246 rating = m_bad;
1247 } else {
1248 rating = m_neutral;
1249 }
1250 //  TODO: Limit this to visible mutations
1251 // TODO: In case invisible mutation turns into visible or vice versa
1252 // print only the visible mutation appearing/disappearing
1253 add_msg_player_or_npc( rating,
1254 _( "Your %1$s mutation turns into %2$s!" ),
1255 _( "<npcname>'s %1$s mutation turns into %2$s!" ),
1256 replace_mdata.name(), mdata.name() );
1257
1258 g->events().send<event_type::evolves_mutation>( getID(), replace_mdata.id, mdata.id );
1259 unset_mutation( replacing );
1260 mutation_replaced = true;
1261 }
1262 if( replacing2 ) {
1263 const auto &replace_mdata = replacing2.obj();
1264 if( mdata.mixed_effect || replace_mdata.mixed_effect ) {
1265 rating = m_mixed;
1266 } else if( replace_mdata.points - mdata.points < 0 ) {
1267 rating = m_good;
1268 } else if( mdata.points - replace_mdata.points < 0 ) {
1269 rating = m_bad;
1270 } else {
1271 rating = m_neutral;
1272 }
1273 add_msg_player_or_npc( rating,
1274 _( "Your %1$s mutation turns into %2$s!" ),
1275 _( "<npcname>'s %1$s mutation turns into %2$s!" ),
1276 replace_mdata.name(), mdata.name() );
1277 g->events().send<event_type::evolves_mutation>( getID(), replace_mdata.id, mdata.id );
1278 unset_mutation( replacing2 );
1279 mutation_replaced = true;
1280 }
1281 for( const auto &i : canceltrait ) {
1282 const auto &cancel_mdata = i.obj();
1283 if( mdata.mixed_effect || cancel_mdata.mixed_effect ) {
1284 rating = m_mixed;
1285 } else if( mdata.points < cancel_mdata.points ) {
1286 rating = m_bad;
1287 } else if( mdata.points > cancel_mdata.points ) {
1288 rating = m_good;
1289 } else if( mdata.points == cancel_mdata.points ) {
1290 rating = m_neutral;
1291 } else {
1292 rating = m_mixed;
1293 }
1294 // If this new mutation cancels a base trait, remove it and add the mutation at the same time
1295 add_msg_player_or_npc( rating,
1296 _( "Your innate %1$s trait turns into %2$s!" ),
1297 _( "<npcname>'s innate %1$s trait turns into %2$s!" ),
1298 cancel_mdata.name(), mdata.name() );
1299 g->events().send<event_type::evolves_mutation>( getID(), cancel_mdata.id, mdata.id );
1300 unset_mutation( i );
1301 mutation_replaced = true;
1302 }
1303 if( !mutation_replaced ) {
1304 if( mdata.mixed_effect ) {
1305 rating = m_mixed;
1306 } else if( mdata.points > 0 ) {
1307 rating = m_good;
1308 } else if( mdata.points < 0 ) {
1309 rating = m_bad;
1310 } else {
1311 rating = m_neutral;
1312 }
1313 // TODO: Limit to visible mutations
1314 add_msg_player_or_npc( rating,
1315 _( "You gain a mutation called %s!" ),
1316 _( "<npcname> gains a mutation called %s!" ),
1317 mdata.name() );
1318 g->events().send<event_type::gains_mutation>( getID(), mdata.id );
1319 }
1320
1321 set_mutation( mut );
1322
1325 return true;
1326}
static bool same_type(const std::list< item > &items)
void remove_child_flag(const trait_id &flag)
Removes the mutation's child flag from the player's list.
Definition: mutation.cpp:1486
void drench_mut_calc()
Recalculates mutation drench protection for all bodyparts (ignored/good/neutral stats)
Definition: character.cpp:7773
void set_highest_cat_level()
Recalculates mutation_category_level[] values for the player.
Definition: character.cpp:7750
@ cancel
Definition: craft_command.h:28
game_message_type
Definition: enums.h:259
static std::vector< trait_id > get_all_mutation_prereqs(const trait_id &id)
Definition: mutation.cpp:1071
std::vector< trait_id > get_mutations_in_types(const std::set< std::string > &ids)
trait_id id
Definition: mutation.h:76
bool threshold
Definition: mutation.h:83
std::set< std::string > types
Definition: mutation.h:261
bool profession
Definition: mutation.h:85
std::vector< trait_id > threshreq
Definition: mutation.h:260
bool mixed_effect
Definition: mutation.h:91

References _, Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), cancel, mutation_branch::cancels, drench_mut_calc(), evolves_mutation, detail::find(), g, gains_mutation, get_all_mutation_prereqs(), get_mutations_in_types(), getID(), has_base_trait(), has_child_flag(), has_trait(), mutation_branch::id, m_bad, m_good, m_mixed, m_neutral, mutation_branch::mixed_effect, mutate_towards(), mutation_branch::name(), string_id< mutation_branch >::NULL_ID(), string_id< T >::obj(), mutation_branch::points, mutation_branch::prereqs, mutation_branch::prereqs2, mutation_branch::profession, remove_child_flag(), remove_mutation(), same_type(), set_highest_cat_level(), set_mutation(), mutation_branch::threshold, mutation_branch::threshreq, mutation_branch::types, and unset_mutation().

◆ mutate_towards() [2/2]

bool Character::mutate_towards ( std::vector< trait_id muts,
int  num_tries = INT_MAX 
)

Mutates toward one of the given mutations, upgrading or removing conflicts if necessary.

Definition at line 1087 of file mutation.cpp.

1088{
1089 while( !muts.empty() && num_tries > 0 ) {
1090 int i = rng( 0, muts.size() - 1 );
1091
1092 if( mutate_towards( muts[i] ) ) {
1093 return true;
1094 }
1095
1096 muts.erase( muts.begin() + i );
1097 --num_tries;
1098 }
1099
1100 return false;
1101}

References mutate_towards(), and rng().

Referenced by mutate(), spell_effect::mutate(), mutate_category(), mutate_towards(), old_mutate(), and debug_menu::wishmutate().

◆ mutation_armor() [1/3]

resistances Character::mutation_armor ( bodypart_id  bp) const

Returns resistances on a body part provided by mutations.

Definition at line 6390 of file character.cpp.

6391{
6392 resistances res;
6393 for( const trait_id &iter : get_mutations() ) {
6394 res += iter->damage_resistance( bp->token );
6395 }
6396
6397 return res;
6398}

References get_mutations().

Referenced by get_all_armor_type(), get_armor_bash_base(), get_armor_bullet_base(), get_armor_cut_base(), get_armor_type(), mutation_armor(), and passive_absorb_hit().

◆ mutation_armor() [2/3]

float Character::mutation_armor ( bodypart_id  bp,
const damage_unit du 
) const

Definition at line 6405 of file character.cpp.

6406{
6407 return mutation_armor( bp ).get_effective_resist( du );
6408}
float get_effective_resist(const damage_unit &du) const
Definition: damage.cpp:217

References resistances::get_effective_resist(), and mutation_armor().

◆ mutation_armor() [3/3]

float Character::mutation_armor ( bodypart_id  bp,
damage_type  dt 
) const

Definition at line 6400 of file character.cpp.

6401{
6402 return mutation_armor( bp ).type_resist( dt );
6403}
float type_resist(damage_type dt) const
Definition: damage.cpp:213

References mutation_armor(), and resistances::type_resist().

◆ mutation_attacks()

std::vector< special_attack > Character::mutation_attacks ( Creature t) const

Returns a vector of valid mutation attacks.

Unarmed increases chance of attacking with mutated body parts Dexterity increases chance of attacking with mutated body parts

Definition at line 1961 of file melee.cpp.

1962{
1963 std::vector<special_attack> ret;
1964
1965 std::string target = t.disp_name();
1966
1967 const body_part_set usable_body_parts = exclusive_flag_coverage( "ALLOWS_NATURAL_ATTACKS" );
1968 const int unarmed = get_skill_level( skill_unarmed );
1969
1970 for( const trait_id &pr : get_mutations() ) {
1971 const mutation_branch &branch = pr.obj();
1972 for( const mut_attack &mut_atk : branch.attacks_granted ) {
1973 // Covered body part
1974 if( mut_atk.bp != num_bp && !usable_body_parts.test( mut_atk.bp ) ) {
1975 continue;
1976 }
1977
1978 /** @EFFECT_UNARMED increases chance of attacking with mutated body parts */
1979 /** @EFFECT_DEX increases chance of attacking with mutated body parts */
1980
1981 // Calculate actor ability value to be compared against mutation attack difficulty and add debug message
1982 const int proc_value = get_dex() + unarmed;
1983 add_msg( m_debug, "%s proc chance: %d in %d", pr.c_str(), proc_value, mut_atk.chance );
1984 // If the mutation attack fails to proc, bail out
1985 if( !x_in_y( proc_value, mut_atk.chance ) ) {
1986 continue;
1987 }
1988
1989 // If player has any blocker, bail out
1990 if( std::any_of( mut_atk.blocker_mutations.begin(), mut_atk.blocker_mutations.end(),
1991 [this]( const trait_id & blocker ) {
1992 return has_trait( blocker );
1993 } ) ) {
1994 add_msg( m_debug, "%s not procing: blocked", pr.c_str() );
1995 continue;
1996 }
1997
1998 // Player must have all needed traits
1999 if( !std::all_of( mut_atk.required_mutations.begin(), mut_atk.required_mutations.end(),
2000 [this]( const trait_id & need ) {
2001 return has_trait( need );
2002 } ) ) {
2003 add_msg( m_debug, "%s not procing: unmet req", pr.c_str() );
2004 continue;
2005 }
2006
2007 special_attack tmp;
2008 // Ugly special case: player's strings have only 1 variable, NPC have 2
2009 // Can't use <npcname> here
2010 // TODO: Fix
2011 if( is_player() ) {
2012 tmp.text = string_format( _( mut_atk.attack_text_u ), target );
2013 } else {
2014 tmp.text = string_format( _( mut_atk.attack_text_npc ), name, target );
2015 }
2016
2017 // Attack starts here
2018 if( mut_atk.hardcoded_effect ) {
2019 tmp.damage = hardcoded_mutation_attack( *this, pr );
2020 } else {
2021 damage_instance dam = mut_atk.base_damage;
2022 damage_instance scaled = mut_atk.strength_damage;
2023 scaled.mult_damage( std::min<float>( 15.0f, get_str() ), true );
2024 dam.add( scaled );
2025
2026 tmp.damage = dam;
2027 }
2028
2029 if( tmp.damage.total_damage() > 0.0f ) {
2030 ret.emplace_back( tmp );
2031 } else {
2032 add_msg( m_debug, "%s not procing: zero damage", pr.c_str() );
2033 }
2034 }
2035 }
2036
2037 return ret;
2038}
static damage_instance hardcoded_mutation_attack(const Character &u, const trait_id &id)
Definition: melee.cpp:1907
float total_damage() const
Definition: damage.cpp:75
void add(const damage_instance &added_di)
Definition: damage.cpp:93
std::string attack_text_u
Text printed when the attack is proced by you.
Definition: mutation.h:39
std::set< trait_id > blocker_mutations
Need none of those to qualify for this attack.
Definition: mutation.h:45
std::set< trait_id > required_mutations
Need all of those to qualify for this attack.
Definition: mutation.h:43
int chance
Chance to proc is one_in( chance - dex - unarmed )
Definition: mutation.h:51
body_part bp
If not num_bp, this body part needs to be uncovered for the attack to proc.
Definition: mutation.h:48
damage_instance base_damage
Definition: mutation.h:53
bool hardcoded_effect
Should be true when and only when this attack needs hardcoded handling.
Definition: mutation.h:58
damage_instance strength_damage
Multiplied by strength and added to the above.
Definition: mutation.h:55
std::string attack_text_npc
As above, but for npc.
Definition: mutation.h:41
std::vector< mut_attack > attacks_granted
Attacks granted by this mutation.
Definition: mutation.h:250
std::string text
Definition: character.h:189
damage_instance damage
Definition: character.h:190

References _, damage_instance::add(), add_msg(), mut_attack::attack_text_npc, mut_attack::attack_text_u, mutation_branch::attacks_granted, mut_attack::base_damage, mut_attack::blocker_mutations, mut_attack::bp, mut_attack::chance, special_attack::damage, Creature::disp_name(), exclusive_flag_coverage(), get_dex(), get_mutations(), get_skill_level(), get_str(), mut_attack::hardcoded_effect, hardcoded_mutation_attack(), Creature::is_player(), m_debug, damage_instance::mult_damage(), name, num_bp, mut_attack::required_mutations, cata::hash64_detail::ret, skill_unarmed, mut_attack::strength_damage, string_format(), body_part_set::test(), special_attack::text, damage_instance::total_damage(), and x_in_y().

Referenced by perform_special_attacks().

◆ mutation_chances()

std::map< trait_id, float > Character::mutation_chances ( ) const

Calculate percentage chances for mutations.

Definition at line 742 of file mutation.cpp.

743{
744 bool force_bad = false;
745 const bool force_good = false;
747 force_bad = true;
748 }
749
750 int current_score = genetic_score( *this );
751 // 10/10/10/10 in stats, balanced traits, plus tip
752 int expected_score = 4 * 10 + 6;
753 int direction = expected_score - current_score;
754
755 // Duplicates allowed - they'll increase chances of change
756 std::vector<potential_mutation> potential;
757
758 for( const mutation_branch &traits_iter : mutation_branch::get_all() ) {
759 const trait_id &base_mutation = traits_iter.id;
760 const mutation_branch &base_mdata = traits_iter;
761 bool thresh_save = base_mdata.threshold;
762 bool prof_save = base_mdata.profession;
763 bool purify_save = !base_mdata.purifiable;
764 bool can_remove = !thresh_save && !prof_save && !purify_save;
765
766 if( has_trait( base_mutation ) ) {
767 for( const trait_id &mutation : base_mdata.replacements ) {
768 if( mutation->valid && mutation_ok( mutation, force_good, force_bad ) ) {
769 potential.emplace_back( base_mutation, mutation, 3 );
770 }
771 }
772
773 for( const trait_id &mutation : base_mdata.additions ) {
774 if( mutation->valid && mutation_ok( mutation, force_good, force_bad ) ) {
775 potential.emplace_back( trait_id::NULL_ID(), mutation, 3 );
776 }
777 }
778
779 // Removal or downgrade (if possible)
780 if( can_remove ) {
781 potential.emplace_back( base_mutation, trait_id::NULL_ID(), 2 );
782 }
783 } else {
784 // Addition from nothing
785 // Duplicates addition above, but that's OK, we need to handle dupes anyway
786 if( base_mutation->valid && mutation_ok( base_mutation, force_good, force_bad ) ) {
787 potential.emplace_back( trait_id::NULL_ID(), base_mutation, 1 );
788 }
789 }
790 }
791
792 // We need all mutation categories in here
793 std::map<std::string, int> padded_mut_cat_lvl = mutation_category_level;
794 for( const mutation_branch &traits_iter : mutation_branch::get_all() ) {
795 for( const std::string &cat : traits_iter.category ) {
796 // Will do nothing if it exists already
797 padded_mut_cat_lvl.insert( std::make_pair( cat, 0 ) );
798 }
799 }
800
801 const std::map<std::string, float> add_weighs =
802 calc_category_weights( padded_mut_cat_lvl, true );
803 const std::map<std::string, float> rem_weighs =
804 calc_category_weights( padded_mut_cat_lvl, false );
805
806 // Not normalized
807 std::map<trait_id, float> chances;
808
809 // Warning: has duplicates
810 for( const potential_mutation &pm : potential ) {
811 int cost_from = pm.from.is_valid() ? pm.from->cost : 0;
812 int cost_to = pm.to.is_valid() ? pm.to->cost : 0;
813 int score_diff = cost_to - cost_from;
814
815 if( pm.to.is_valid() ) {
816 float cat_mod = std::accumulate( pm.to->category.begin(), pm.to->category.end(), 0.0f,
817 [&add_weighs]( float m, const std::string & cat ) {
818 return std::max( m, add_weighs.at( cat ) );
819 } );
820 float c = score_difference_to_chance( direction + score_diff );
821 chances[pm.to] += c * cat_mod;
822 } else if( pm.from.is_valid() ) {
823 float cat_mod = std::accumulate( pm.from->category.begin(), pm.from->category.end(), 0.0f,
824 [&rem_weighs]( float m, const std::string & cat ) {
825 return std::min( m, rem_weighs.at( cat ) );
826 } );
827 float c = score_difference_to_chance( direction - score_diff );
828 chances[pm.from] += c * cat_mod;
829 }
830 }
831
832 return normalized_map( chances );
833}
direction
Definition: line.h:39
constexpr double c
Definition: magic.cpp:1032
static float score_difference_to_chance(float diff)
Definition: mutation.cpp:680
static T normalized_map(const T &ctn)
Definition: mutation.cpp:689
static int genetic_score(const Character &c)
Definition: mutation.cpp:673
static std::map< std::string, float > calc_category_weights(const std::map< std::string, int > &mcl, bool addition)
Definition: mutation.cpp:709
static const std::vector< mutation_branch > & get_all()
All known mutations.
bool purifiable
Definition: mutation.h:81
std::vector< trait_id > additions
Definition: mutation.h:264

References mutation_branch::additions, c, calc_category_weights(), genetic_score(), mutation_branch::get_all(), has_trait(), string_id< T >::id(), mutation_category_level, mutation_ok(), normalized_map(), string_id< mutation_branch >::NULL_ID(), mutation_branch::profession, mutation_branch::purifiable, mutation_branch::replacements, score_difference_to_chance(), mutation_branch::threshold, trait_CHAOTIC_BAD, and mutation_branch::valid.

Referenced by debug_menu::debug(), and mutate().

◆ mutation_effect()

void Character::mutation_effect ( const trait_id mut)

Handles things like removal of armor, etc.

Definition at line 258 of file mutation.cpp.

259{
260 if( mut == trait_GLASSJAW ) {
261 recalc_hp();
262
263 } else if( mut == trait_STR_ALPHA ) {
264 if( str_max < 16 ) {
265 str_max = 8 + str_max / 2;
266 }
267 apply_mods( mut, true );
268 recalc_hp();
269 } else if( mut == trait_DEX_ALPHA ) {
270 if( dex_max < 16 ) {
271 dex_max = 8 + dex_max / 2;
272 }
273 apply_mods( mut, true );
274 } else if( mut == trait_INT_ALPHA ) {
275 if( int_max < 16 ) {
276 int_max = 8 + int_max / 2;
277 }
278 apply_mods( mut, true );
279 } else if( mut == trait_INT_SLIME ) {
280 int_max *= 2; // Now, can you keep it? :-)
281
282 } else if( mut == trait_PER_ALPHA ) {
283 if( per_max < 16 ) {
284 per_max = 8 + per_max / 2;
285 }
286 apply_mods( mut, true );
287 } else {
288 apply_mods( mut, true );
289 }
290
292
293 const auto &branch = mut.obj();
294 if( branch.hp_modifier != 0.0f || branch.hp_modifier_secondary != 0.0f ||
295 branch.hp_adjustment != 0.0f ) {
296 recalc_hp();
297 }
298
299 remove_worn_items_with( [&]( item & armor ) {
300 static const std::string mutation_safe = "OVERSIZE";
301 if( armor.has_flag( mutation_safe ) ) {
302 return false;
303 }
304 if( !branch.conflicts_with_item( armor ) ) {
305 return false;
306 }
307
309 _( "Your %s is pushed off!" ),
310 _( "<npcname>'s %s is pushed off!" ),
311 armor.tname() );
312 get_map().add_item_or_charges( pos(), armor );
313 return true;
314 } );
315
316 if( branch.starts_active ) {
317 my_mutations[mut].powered = true;
318 }
319
320 on_mutation_gain( mut );
321}
std::list< item > remove_worn_items_with(std::function< bool(item &)> filter)
Similar to remove_items_with, but considers only worn items and not their content (item::contents is ...
Definition: character.cpp:2265
static const trait_id trait_PER_ALPHA("PER_ALPHA")
static const trait_id trait_STR_ALPHA("STR_ALPHA")
static const trait_id trait_GLASSJAW("GLASSJAW")
static const trait_id trait_DEX_ALPHA("DEX_ALPHA")
static const trait_id trait_INT_SLIME("INT_SLIME")
static const trait_id trait_INT_ALPHA("INT_ALPHA")

References _, Creature::add_msg_player_or_npc(), apply_mods(), dex_max, get_map(), item::has_flag(), int_max, m_bad, my_mutations, string_id< T >::obj(), on_mutation_gain(), per_max, pos(), recalc_hp(), recalculate_size(), remove_worn_items_with(), str_max, item::tname(), trait_DEX_ALPHA, trait_GLASSJAW, trait_INT_ALPHA, trait_INT_SLIME, trait_PER_ALPHA, and trait_STR_ALPHA.

Referenced by on_item_wear(), set_mutation(), and switch_mutations().

◆ mutation_loss_effect()

void Character::mutation_loss_effect ( const trait_id mut)

Handles what happens when you lose a mutation.

Definition at line 323 of file mutation.cpp.

324{
325 if( mut == trait_GLASSJAW ) {
326 recalc_hp();
327
328 } else if( mut == trait_STR_ALPHA ) {
329 apply_mods( mut, false );
330 if( str_max < 16 ) {
331 str_max = 2 * ( str_max - 8 );
332 }
333 recalc_hp();
334 } else if( mut == trait_DEX_ALPHA ) {
335 apply_mods( mut, false );
336 if( dex_max < 16 ) {
337 dex_max = 2 * ( dex_max - 8 );
338 }
339 } else if( mut == trait_INT_ALPHA ) {
340 apply_mods( mut, false );
341 if( int_max < 16 ) {
342 int_max = 2 * ( int_max - 8 );
343 }
344 } else if( mut == trait_INT_SLIME ) {
345 int_max /= 2; // In case you have a freak accident with the debug menu ;-)
346
347 } else if( mut == trait_PER_ALPHA ) {
348 apply_mods( mut, false );
349 if( per_max < 16 ) {
350 per_max = 2 * ( per_max - 8 );
351 }
352 } else {
353 apply_mods( mut, false );
354 }
355
357
358 const auto &branch = mut.obj();
359 if( branch.hp_modifier != 0.0f || branch.hp_modifier_secondary != 0.0f ||
360 branch.hp_adjustment != 0.0f ) {
361 recalc_hp();
362 }
363
364 on_mutation_loss( mut );
365}
void on_mutation_loss(const trait_id &mid)
Called when a mutation is lost.
Definition: character.cpp:9854

References apply_mods(), dex_max, int_max, string_id< T >::obj(), on_mutation_loss(), per_max, recalc_hp(), recalculate_size(), str_max, trait_DEX_ALPHA, trait_GLASSJAW, trait_INT_ALPHA, trait_INT_SLIME, trait_PER_ALPHA, and trait_STR_ALPHA.

Referenced by on_item_takeoff(), switch_mutations(), and unset_mutation().

◆ mutation_ok()

bool Character::mutation_ok ( const trait_id mutation,
bool  force_good,
bool  force_bad 
) const

Returns true if the player doesn't have the mutation or a conflicting one and it complies with the force typing.

Definition at line 629 of file mutation.cpp.

630{
631 if( !is_category_allowed( mutation->category ) ) {
632 return false;
633 }
634 if( mutation_branch::trait_is_blacklisted( mutation ) ) {
635 return false;
636 }
637 if( has_trait( mutation ) || has_child_flag( mutation ) ) {
638 // We already have this mutation or something that replaces it.
639 return false;
640 }
641
642 for( const bionic_id &bid : get_bionics() ) {
643 for( const trait_id &mid : bid->canceled_mutations ) {
644 if( mid == mutation ) {
645 return false;
646 }
647 }
648 }
649
650 const mutation_branch &mdata = mutation.obj();
651 if( force_bad && mdata.points > 0 ) {
652 // This is a good mutation, and we're due for a bad one.
653 return false;
654 }
655
656 if( force_good && mdata.points < 0 ) {
657 // This is a bad mutation, and we're due for a good one.
658 return false;
659 }
660
661 return true;
662}
bool is_category_allowed(const std::vector< std::string > &category) const
Returns true if this category of mutation is allowed.
Definition: mutation.cpp:373
std::vector< std::string > category
Definition: mutation.h:265
static bool trait_is_blacklisted(const trait_id &tid)
Check if the trait with the given ID is blacklisted.

References mutation_branch::category, get_bionics(), has_child_flag(), has_trait(), is_category_allowed(), string_id< T >::obj(), mutation_branch::points, and mutation_branch::trait_is_blacklisted().

Referenced by mutate_category(), mutation_chances(), and old_mutate().

◆ mutation_spend_resources()

void Character::mutation_spend_resources ( const trait_id mut)

Removes the appropriate costs (NOTE: will reapply mods & recalc sightlines in case of newly activated mutation).

Definition at line 1713 of file mutation.cpp.

1714{
1715 const mutation_branch &mdata = mut.obj();
1716 char_trait_data &tdata = my_mutations[mut];
1717 int cost = mdata.cost;
1718 if( tdata.powered && tdata.charge > 0 ) {
1719 // Already-on units just lose a bit of charge
1720 tdata.charge--;
1721 } else {
1722 // Not-on units, or those with zero charge, have to pay the power cost
1723 if( mdata.cooldown > 0 ) {
1724 tdata.charge = mdata.cooldown - 1;
1725 }
1726 if( mdata.hunger ) {
1727 // burn some energy
1728 mod_stored_kcal( -cost * 6 );
1729 }
1730 if( mdata.thirst ) {
1731 mod_thirst( cost );
1732 }
1733 if( mdata.fatigue ) {
1734 mod_fatigue( cost );
1735 }
1736
1737 // Handle stat changes from activation
1738 apply_mods( mut, true );
1740 }
1741}
int charge
Time (in turns) until the mutation increase hunger/thirst/fatigue according to its cost (mutation_bra...
Definition: character.h:210

References apply_mods(), char_trait_data::charge, mutation_branch::cooldown, mutation_branch::cost, mutation_branch::fatigue, mutation_branch::hunger, mod_fatigue(), mod_stored_kcal(), mod_thirst(), my_mutations, string_id< T >::obj(), char_trait_data::powered, recalc_sight_limits(), and mutation_branch::thirst.

Referenced by activate_mutation(), iexamine::ledge(), and game::vertical_move().

◆ mutation_value()

float Character::mutation_value ( const std::string &  val) const

Goes over all mutations, gets min and max of a value with given name.

Returns
min( 0, lowest ) + max( 0, highest )

Definition at line 6605 of file character.cpp.

6606{
6607 // Syntax similar to tuple get<n>()
6608 const auto found = mutation_value_map.find( val );
6609
6610 if( found == mutation_value_map.end() ) {
6611 debugmsg( "Invalid mutation value name %s", val );
6612 return 0.0f;
6613 } else {
6614 return found->second( cached_mutations );
6615 }
6616}
static const std::map< std::string, std::function< float(std::vector< const mutation_branch * >)> > mutation_value_map
Definition: character.cpp:6567

References cached_mutations, debugmsg, and mutation_value_map.

Referenced by attack_cost(), calc_needs_rates(), draw_speed_tab(), get_stamina_max(), healing_rate(), healing_rate_medicine(), hearing_ability(), is_immune_effect(), known_magic::mana_regen_rate(), known_magic::max_mana(), mend(), metabolic_rate_base(), overmap_sight_range(), read_speed(), recalc_hp(), recalc_speed_bonus(), regen(), reset_stats(), run_cost(), rust_rate(), swim_speed(), update_stamina(), visibility(), game::walk_move(), and weight_capacity().

◆ natural_attack_restricted_on()

bool Character::natural_attack_restricted_on ( const bodypart_id bp) const

Returns true if the character is wearing something on the entered body_part, ignoring items with the ALLOWS_NATURAL_ATTACKS flag.

Definition at line 1763 of file character.cpp.

1764{
1765 for( const item &i : worn ) {
1766 if( i.covers( bp->token ) && !i.has_flag( "ALLOWS_NATURAL_ATTACKS" ) &&
1767 !i.has_flag( "SEMITANGIBLE" ) &&
1768 !i.has_flag( "PERSONAL" ) && !i.has_flag( "AURA" ) ) {
1769 return true;
1770 }
1771 }
1772 return false;
1773}

References worn.

Referenced by roll_bash_damage(), roll_cut_damage(), and roll_stab_damage().

◆ nearby()

std::vector< item_location > Character::nearby ( const std::function< bool(const item *, const item *)> &  func,
int  radius = 1 
) const

Returns nearby items which match the provided predicate.

Definition at line 2170 of file character.cpp.

2172{
2173 std::vector<item_location> res;
2174
2175 visit_items( [&]( const item * e, const item * parent ) {
2176 if( func( e, parent ) ) {
2177 res.emplace_back( const_cast<Character &>( *this ), const_cast<item *>( e ) );
2178 }
2179 return VisitResponse::NEXT;
2180 } );
2181
2182 for( const auto &cur : map_selector( pos(), radius ) ) {
2183 cur.visit_items( [&]( const item * e, const item * parent ) {
2184 if( func( e, parent ) ) {
2185 res.emplace_back( cur, const_cast<item *>( e ) );
2186 }
2187 return VisitResponse::NEXT;
2188 } );
2189 }
2190
2191 for( const auto &cur : vehicle_selector( pos(), radius ) ) {
2192 cur.visit_items( [&]( const item * e, const item * parent ) {
2193 if( func( e, parent ) ) {
2194 res.emplace_back( cur, const_cast<item *>( e ) );
2195 }
2196 return VisitResponse::NEXT;
2197 } );
2198 }
2199
2200 return res;
2201}

References NEXT, pos(), and visitable< Character >::visit_items().

Referenced by bandolier_actor::reload(), and npc::within_boundaries_of_camp().

◆ nutrition_for()

int Character::nutrition_for ( const item comest) const

Handles the nutrition value for a comestible.

Definition at line 467 of file consumption.cpp.

468{
470}
static constexpr float kcal_per_nutr
1 nutr ~= 8.7kcal (1 nutr/5min = 288 nutr/day at 2500kcal/day)
Definition: itype.h:180
int kcal
amount of kcal this food has
Definition: stomach.h:18

References compute_effective_nutrients(), nutrients::kcal, and islot_comestible::kcal_per_nutr.

Referenced by iuse::blech(), consume_effects(), npc::decide_needs(), eat(), iuse::plantblech(), and npc::value().

◆ old_mutate()

void Character::old_mutate ( )
private

Definition at line 877 of file mutation.cpp.

878{
879 bool force_bad = one_in( 3 );
880 bool force_good = false;
881 if( has_trait( trait_ROBUST ) && force_bad ) {
882 // Robust Genetics gives you a 33% chance for a good mutation,
883 // instead of the 33% chance of a bad one.
884 force_bad = false;
885 force_good = true;
886 }
888 force_bad = true;
889 force_good = false;
890 }
891
892 // Determine the highest mutation category
893 std::string cat = get_highest_category();
894
895 if( !is_category_allowed( cat ) ) {
896 cat.clear();
897 }
898
899 // See if we should upgrade/extend an existing mutation...
900 std::vector<trait_id> upgrades;
901
902 // ... or remove one that is not in our highest category
903 std::vector<trait_id> downgrades;
904
905 // For each mutation...
906 for( const mutation_branch &traits_iter : mutation_branch::get_all() ) {
907 const trait_id &base_mutation = traits_iter.id;
908 const mutation_branch &base_mdata = traits_iter;
909 bool thresh_save = base_mdata.threshold;
910 bool prof_save = base_mdata.profession;
911 // are we unpurifiable? (saved from mutating away)
912 bool purify_save = !base_mdata.purifiable;
913
914 // ...that we have...
915 if( has_trait( base_mutation ) ) {
916 // ...consider the mutations that replace it.
917 for( const trait_id &mutation : base_mdata.replacements ) {
918 bool valid_ok = mutation->valid;
919
920 if( ( mutation_ok( mutation, force_good, force_bad ) ) &&
921 ( valid_ok ) ) {
922 upgrades.push_back( mutation );
923 }
924 }
925
926 // ...consider the mutations that add to it.
927 for( const trait_id &mutation : base_mdata.additions ) {
928 bool valid_ok = mutation->valid;
929
930 if( ( mutation_ok( mutation, force_good, force_bad ) ) &&
931 ( valid_ok ) ) {
932 upgrades.push_back( mutation );
933 }
934 }
935
936 // ...consider whether its in our highest category
937 if( has_trait( base_mutation ) && !has_base_trait( base_mutation ) ) {
938 // Starting traits don't count toward categories
939 std::vector<trait_id> group = mutations_category[cat];
940 bool in_cat = false;
941 for( const trait_id &elem : group ) {
942 if( elem == base_mutation ) {
943 in_cat = true;
944 break;
945 }
946 }
947
948 // mark for removal
949 // no removing Thresholds/Professions this way!
950 // unpurifiable traits also cannot be purified
951 if( !in_cat && !thresh_save && !prof_save && !purify_save ) {
952 if( one_in( 4 ) ) {
953 downgrades.push_back( base_mutation );
954 }
955 }
956 }
957 }
958 }
959
960 // Preliminary round to either upgrade or remove existing mutations
961 if( one_in( 2 ) ) {
962 if( !upgrades.empty() ) {
963 // (upgrade count) chances to pick an upgrade, 4 chances to pick something else.
964 size_t roll = rng( 0, upgrades.size() + 4 );
965 if( roll < upgrades.size() ) {
966 // We got a valid upgrade index, so use it and return.
967 mutate_towards( upgrades[roll] );
968 return;
969 }
970 }
971 } else {
972 // Remove existing mutations that don't fit into our category
973 if( !downgrades.empty() && !cat.empty() ) {
974 size_t roll = rng( 0, downgrades.size() + 4 );
975 if( roll < downgrades.size() ) {
976 remove_mutation( downgrades[roll] );
977 return;
978 }
979 }
980 }
981
982 std::vector<trait_id> valid; // Valid mutations
983 bool first_pass = true;
984
985 do {
986 // If we tried once with a non-NULL category, and couldn't find anything valid
987 // there, try again with empty category
988 // CHAOTIC_BAD lets the game pull from any category by default
989 if( !first_pass || has_trait( trait_CHAOTIC_BAD ) ) {
990 cat.clear();
991 }
992
993 if( cat.empty() ) {
994 // Pull the full list
995 for( const mutation_branch &traits_iter : mutation_branch::get_all() ) {
996 if( traits_iter.valid && is_category_allowed( traits_iter.category ) ) {
997 valid.push_back( traits_iter.id );
998 }
999 }
1000 } else {
1001 // Pull the category's list
1002 valid = mutations_category[cat];
1003 }
1004
1005 // Remove anything we already have, that we have a child of, or that
1006 // goes against our intention of a good/bad mutation
1007 for( size_t i = 0; i < valid.size(); i++ ) {
1008 if( ( !mutation_ok( valid[i], force_good, force_bad ) ) ||
1009 ( !valid[i]->valid ) ) {
1010 valid.erase( valid.begin() + i );
1011 i--;
1012 }
1013 }
1014
1015 if( valid.empty() ) {
1016 // So we won't repeat endlessly
1017 first_pass = false;
1018 }
1019 } while( valid.empty() && !cat.empty() );
1020
1021 if( valid.empty() ) {
1022 // Couldn't find anything at all!
1023 return;
1024 }
1025
1026 if( mutate_towards( random_entry( valid ) ) ) {
1027 return;
1028 } else {
1029 // if mutation failed (errors, post-threshold pick), try again once.
1030 mutate_towards( random_entry( valid ) );
1031 }
1032}
group
Definition: sounds.h:125

References mutation_branch::additions, mutation_branch::get_all(), get_highest_category(), has_base_trait(), has_trait(), string_id< T >::id(), is_category_allowed(), mutate_towards(), mutation_ok(), mutations_category, one_in(), mutation_branch::profession, mutation_branch::purifiable, random_entry(), remove_mutation(), mutation_branch::replacements, rng(), mutation_branch::threshold, trait_CHAOTIC_BAD, trait_ROBUST, and mutation_branch::valid.

Referenced by mutate().

◆ on_damage_of_type()

void Character::on_damage_of_type ( int  adjusted_damage,
damage_type  type,
const bodypart_id bp 
)
overrideprotectedvirtual

Reimplemented from Creature.

Definition at line 4483 of file character.cpp.

4484{
4485 // Electrical damage has a chance to temporarily incapacitate bionics in the damaged body_part.
4486 if( type == DT_ELECTRIC ) {
4487 const time_duration min_disable_time = 10_turns * adjusted_damage;
4488 for( bionic &i : *my_bionics ) {
4489 if( !i.powered ) {
4490 // Unpowered bionics are protected from power surges.
4491 continue;
4492 }
4493 const auto &info = i.info();
4494 if( info.has_flag( STATIC( flag_str_id( "BIONIC_SHOCKPROOF" ) ) )
4495 || info.has_flag( STATIC( flag_str_id( "BIONIC_FAULTY" ) ) ) ) {
4496 continue;
4497 }
4498 const std::map<bodypart_str_id, int> &bodyparts = info.occupied_bodyparts;
4499 if( bodyparts.find( bp.id() ) != bodyparts.end() ) {
4500 const int bp_hp = get_part_hp_cur( bp );
4501 // The chance to incapacitate is as high as 50% if the attack deals damage equal to one third of the body part's current health.
4502 if( x_in_y( adjusted_damage * 3, bp_hp ) && one_in( 2 ) ) {
4503 if( i.incapacitated_time == 0_turns ) {
4504 add_msg_if_player( m_bad, _( "Your %s bionic shorts out!" ), info.name );
4505 }
4506 i.incapacitated_time += rng( min_disable_time, 10 * min_disable_time );
4507 }
4508 }
4509 }
4510 }
4511}
#define STATIC(expr)
The purpose of this macro is to provide a concise syntax for creation of inline literals (std::string...
Definition: make_static.h:24
string_id< json_flag > flag_str_id
Definition: type_id.h:210

References _, Creature::add_msg_if_player(), DT_ELECTRIC, Creature::get_part_hp_cur(), int_id< T >::id(), m_bad, my_bionics, one_in(), rng(), STATIC, type, and x_in_y().

◆ on_dodge()

void Character::on_dodge ( Creature source,
int  difficulty 
)
overridevirtual

This creature just dodged an attack - possibly special/ranged attack - from source.

Players should train dodge, monsters may use some special defenses.

Reimplemented from Creature.

Definition at line 8213 of file character.cpp.

8214{
8215 static const matec_id tec_none( "tec_none" );
8216
8217 // Each avoided hit consumes an available dodge
8218 // When no more available we are likely to fail player::dodge_roll
8219 dodges_left--;
8220
8221 // dodging throws of our aim unless we are either skilled at dodging or using a small weapon
8222 if( is_armed() && weapon.is_gun() ) {
8223 recoil += std::max( weapon.volume() / 250_ml - get_skill_level( skill_dodge ), 0 ) * rng( 0, 100 );
8224 recoil = std::min( MAX_RECOIL, recoil );
8225 }
8226
8227 // Even if we are not to train still call practice to prevent skill rust
8228 difficulty = std::max( difficulty, 0 );
8229 as_player()->practice( skill_dodge, difficulty * 2, difficulty );
8230
8231 martial_arts_data->ma_ondodge_effects( *this );
8232
8233 // For adjacent attackers check for techniques usable upon successful dodge
8234 if( source && square_dist( pos(), source->pos() ) == 1 ) {
8235 matec_id tec = pick_technique( *source, used_weapon(), false, true, false );
8236
8237 if( tec != tec_none && !is_dead_state() ) {
8238 if( get_stamina() < get_stamina_max() / 3 ) {
8239 add_msg( m_bad, _( "You try to counterattack but you are too exhausted!" ) );
8240 } else {
8241 melee_attack( *source, false, &tec );
8242 }
8243 }
8244 }
8245}

References _, add_msg(), Creature::as_player(), dodges_left, get_skill_level(), get_stamina(), get_stamina_max(), is_armed(), is_dead_state(), item::is_gun(), m_bad, martial_arts_data, MAX_RECOIL, melee_attack(), pick_technique(), Creature::pos(), pos(), practice(), recoil, rng(), skill_dodge, square_dist(), tec_none, used_weapon(), item::volume(), and weapon.

Referenced by mattack::grab().

◆ on_effect_int_change()

void Character::on_effect_int_change ( const efftype_id effect_type,
int  intensity,
const bodypart_str_id bp 
)
overridevirtual

Called when effect intensity has been changed.

Reimplemented from Creature.

Definition at line 9833 of file character.cpp.

9835{
9836 // Adrenaline can reduce perceived pain (or increase it when you enter comedown).
9837 // See @ref get_perceived_pain()
9839 // Note that calling this does no harm if it wasn't changed.
9840 on_stat_change( "perceived_pain", get_perceived_pain() );
9841 }
9842
9843 morale->on_effect_int_change( effect_type, intensity, bp );
9844}

References effect_adrenaline, get_perceived_pain(), morale, and on_stat_change().

Referenced by load().

◆ on_hit()

void Character::on_hit ( Creature source,
bodypart_id  bp_hit,
dealt_projectile_attack const *  proj 
)
overridevirtual

This creature just got hit by an attack - possibly special/ranged attack - from source.

Parameters
sourceSource creature, can be nullptr
projSource projectile, can be nullptr Players should train dodge, possibly counter-attack somehow.

Implements Creature.

Definition at line 8252 of file character.cpp.

8254{
8256 if( source == nullptr || proj != nullptr ) {
8257 return;
8258 }
8259
8260 bool u_see = g->u.sees( *this );
8261 units::energy trigger_cost_base = bio_ods->power_trigger;
8262 if( has_active_bionic( bio_ods ) && get_power_level() >= trigger_cost_base * 4 ) {
8263 if( is_player() ) {
8264 add_msg( m_good, _( "Your offensive defense system shocks %s in mid-attack!" ),
8265 source->disp_name() );
8266 } else if( u_see ) {
8267 add_msg( _( "%1$s's offensive defense system shocks %2$s in mid-attack!" ),
8268 disp_name(),
8269 source->disp_name() );
8270 }
8271 int shock = rng( 1, 4 );
8272 mod_power_level( -shock * trigger_cost_base );
8273 damage_instance ods_shock_damage;
8274 ods_shock_damage.add_damage( DT_ELECTRIC, shock * 5 );
8275 // Should hit body part used for attack
8276 source->deal_damage( this, bodypart_id( "torso" ), ods_shock_damage );
8277 }
8278 if( !wearing_something_on( bp_hit ) &&
8280 int spine = rng( 1, has_trait( trait_QUILLS ) ? 20 : 8 );
8281 if( !is_player() ) {
8282 if( u_see ) {
8283 add_msg( _( "%1$s's %2$s puncture %3$s in mid-attack!" ), name,
8284 ( has_trait( trait_QUILLS ) ? _( "quills" ) : _( "spines" ) ),
8285 source->disp_name() );
8286 }
8287 } else {
8288 add_msg( m_good, _( "Your %1$s puncture %2$s in mid-attack!" ),
8289 ( has_trait( trait_QUILLS ) ? _( "quills" ) : _( "spines" ) ),
8290 source->disp_name() );
8291 }
8292 damage_instance spine_damage;
8293 spine_damage.add_damage( DT_STAB, spine );
8294 source->deal_damage( this, bodypart_id( "torso" ), spine_damage );
8295 }
8296 if( ( !( wearing_something_on( bp_hit ) ) ) && ( has_trait( trait_THORNS ) ) &&
8297 ( !( source->has_weapon() ) ) ) {
8298 if( !is_player() ) {
8299 if( u_see ) {
8300 add_msg( _( "%1$s's %2$s scrape %3$s in mid-attack!" ), name,
8301 _( "thorns" ), source->disp_name() );
8302 }
8303 } else {
8304 add_msg( m_good, _( "Your thorns scrape %s in mid-attack!" ), source->disp_name() );
8305 }
8306 int thorn = rng( 1, 4 );
8307 damage_instance thorn_damage;
8308 thorn_damage.add_damage( DT_CUT, thorn );
8309 // In general, critters don't have separate limbs
8310 // so safer to target the torso
8311 source->deal_damage( this, bodypart_id( "torso" ), thorn_damage );
8312 }
8313 if( ( !( wearing_something_on( bp_hit ) ) ) && ( has_trait( trait_CF_HAIR ) ) ) {
8314 if( !is_player() ) {
8315 if( u_see ) {
8316 add_msg( _( "%1$s gets a load of %2$s's %3$s stuck in!" ), source->disp_name(),
8317 name, ( _( "hair" ) ) );
8318 }
8319 } else {
8320 add_msg( m_good, _( "Your hairs detach into %s!" ), source->disp_name() );
8321 }
8322 source->add_effect( effect_stunned, 2_turns );
8323 if( one_in( 3 ) ) { // In the eyes!
8324 source->add_effect( effect_blind, 2_turns );
8325 }
8326 }
8327 if( worn_with_flag( "REQUIRES_BALANCE" ) && !has_effect( effect_downed ) ) {
8328 int rolls = 4;
8329 if( worn_with_flag( "ROLLER_ONE" ) ) {
8330 rolls += 2;
8331 }
8332 if( has_trait( trait_PROF_SKATER ) ) {
8333 rolls--;
8334 }
8335 if( has_trait( trait_DEFT ) ) {
8336 rolls--;
8337 }
8338
8339 if( stability_roll() < dice( rolls, 10 ) ) {
8340 if( !is_player() ) {
8341 if( u_see ) {
8342 add_msg( _( "%1$s loses their balance while being hit!" ), name );
8343 }
8344 } else {
8345 add_msg( m_bad, _( "You lose your balance while being hit!" ) );
8346 }
8347 // This kind of downing is not subject to immunity.
8348 add_effect( effect_downed, 2_turns, num_bp, 0, true );
8349 }
8350 }
8351 enchantment_cache->cast_hit_me( *this, source );
8352}
static const trait_id trait_CF_HAIR("CF_HAIR")
static const trait_id trait_QUILLS("QUILLS")
static const trait_id trait_SPINES("SPINES")
static const bionic_id bio_ods("bio_ods")
static const trait_id trait_THORNS("THORNS")
static const trait_id trait_DEFT("DEFT")
static const trait_id trait_PROF_SKATER("PROF_SKATER")
float stability_roll() const override
Returns value of player's stable footing.
virtual bool has_weapon() const =0

References _, damage_instance::add_damage(), Creature::add_effect(), add_msg(), bio_ods, Creature::check_dead_state(), Creature::deal_damage(), dice(), Creature::disp_name(), disp_name(), DT_CUT, DT_ELECTRIC, DT_STAB, effect_blind, effect_downed, effect_stunned, enchantment_cache, g, get_power_level(), has_active_bionic(), Creature::has_effect(), has_trait(), Creature::has_weapon(), Creature::is_player(), m_bad, m_good, mod_power_level(), name, num_bp, one_in(), bionic_data::power_trigger, rng(), stability_roll(), trait_CF_HAIR, trait_DEFT, trait_PROF_SKATER, trait_QUILLS, trait_SPINES, trait_THORNS, wearing_something_on(), and worn_with_flag().

Referenced by melee_attack().

◆ on_hurt()

void Character::on_hurt ( Creature source,
bool  disturb = true 
)

Handles effects that happen when the player is damaged and aware of the fact.

Definition at line 8648 of file character.cpp.

8649{
8651 ( get_part_hp_cur( bodypart_id( "head" ) ) < 25 ||
8652 get_part_hp_cur( bodypart_id( "torso" ) ) < 15 ) ) {
8653 add_effect( effect_adrenaline, 20_minutes );
8654 }
8655
8656 if( disturb ) {
8658 wake_up();
8659 }
8660 if( !is_npc() && !has_effect( effect_narcosis ) ) {
8661 if( source != nullptr ) {
8662 g->cancel_activity_or_ignore_query( distraction_type::attacked,
8663 string_format( _( "You were attacked by %s!" ),
8664 source->disp_name() ) );
8665 } else {
8666 g->cancel_activity_or_ignore_query( distraction_type::attacked, _( "You were hurt!" ) );
8667 }
8668 }
8669 }
8670}
static const trait_id trait_ADRENALINE("ADRENALINE")

References _, Creature::add_effect(), attacked, Creature::disp_name(), effect_adrenaline, effect_narcosis, effect_sleep, g, Creature::get_part_hp_cur(), Creature::has_effect(), has_trait(), Creature::is_npc(), string_format(), trait_ADRENALINE, and wake_up().

Referenced by apply_damage(), deal_damage(), and hurtall().

◆ on_item_takeoff()

void Character::on_item_takeoff ( const item it)

Called when an item is taken off.

Definition at line 9820 of file character.cpp.

9821{
9822 for( const trait_id &mut : it.mutations_from_wearing( *this ) ) {
9823 mutation_loss_effect( mut );
9826 if( get_stamina() > get_stamina_max() ) {
9828 }
9829 }
9830 morale->on_item_takeoff( it );
9831}
void mutation_loss_effect(const trait_id &mut)
Handles what happens when you lose a mutation.
Definition: mutation.cpp:323
std::vector< trait_id > mutations_from_wearing(const Character &guy) const
Definition: item.cpp:9076

References calc_encumbrance(), get_stamina(), get_stamina_max(), morale, mutation_loss_effect(), item::mutations_from_wearing(), recalc_sight_limits(), and set_stamina().

Referenced by item::on_takeoff().

◆ on_item_wear()

void Character::on_item_wear ( const item it)

Called when an item is worn.

Definition at line 9805 of file character.cpp.

9806{
9807 for( const trait_id &mut : it.mutations_from_wearing( *this ) ) {
9808 mutation_effect( mut );
9811
9812 // If the stamina is higher than the max (Languorous), set it back to max
9813 if( get_stamina() > get_stamina_max() ) {
9815 }
9816 }
9817 morale->on_item_wear( it );
9818}
void mutation_effect(const trait_id &mut)
Handles things like removal of armor, etc.
Definition: mutation.cpp:258

References calc_encumbrance(), get_stamina(), get_stamina_max(), morale, mutation_effect(), item::mutations_from_wearing(), recalc_sight_limits(), and set_stamina().

Referenced by debug_menu::character_edit_menu(), load(), and item::on_wear().

◆ on_mutation_gain()

void Character::on_mutation_gain ( const trait_id mid)

Called when a mutation is gained.

Definition at line 9846 of file character.cpp.

9847{
9848 morale->on_mutation_gain( mid );
9849 magic->on_mutation_gain( mid, *this );
9850 update_type_of_scent( mid );
9851 recalculate_enchantment_cache(); // mutations can have enchantments
9852}

References magic, morale, recalculate_enchantment_cache(), and update_type_of_scent().

Referenced by add_bionic(), known_magic::learn_spell(), load(), and mutation_effect().

◆ on_mutation_loss()

void Character::on_mutation_loss ( const trait_id mid)

Called when a mutation is lost.

Definition at line 9854 of file character.cpp.

9855{
9856 morale->on_mutation_loss( mid );
9857 magic->on_mutation_loss( mid );
9858 update_type_of_scent( mid, false );
9859 recalculate_enchantment_cache(); // mutations can have enchantments
9860}

References magic, morale, recalculate_enchantment_cache(), and update_type_of_scent().

Referenced by mutation_loss_effect().

◆ on_stat_change()

void Character::on_stat_change ( const std::string &  stat,
int  value 
)
overridevirtual

Called when a stat is changed.

Reimplemented from Creature.

Definition at line 9862 of file character.cpp.

9863{
9864 morale->on_stat_change( stat, value );
9865}

References morale.

Referenced by load(), on_effect_int_change(), set_fatigue(), set_pain(), set_painkiller(), and set_thirst().

◆ on_worn_item_transform()

void Character::on_worn_item_transform ( const item old_it,
const item new_it 
)

Called when a worn item is transformed.

Definition at line 9867 of file character.cpp.

9868{
9869 morale->on_worn_item_transform( old_it, new_it );
9870}

References morale.

Referenced by iuse_transform::use().

◆ on_worn_item_washed()

void Character::on_worn_item_washed ( const item it)

Called when an item is washed.

Definition at line 9798 of file character.cpp.

9799{
9800 if( is_worn( it ) ) {
9801 morale->on_worn_item_washed( it );
9802 }
9803}

References is_worn(), and morale.

Referenced by wash_activity_actor::finish().

◆ operator=() [1/2]

Character & Character::operator= ( Character &&  )
protecteddefault

◆ operator=() [2/2]

Character & Character::operator= ( const Character )
delete

◆ overmap_los()

bool Character::overmap_los ( const tripoint_abs_omt omt,
int  sight_points 
)

Returns true if overmap tile is within player line-of-sight.

Definition at line 621 of file character.cpp.

622{
624 const point_rel_omt offset = omt.xy() - ompos.xy();
625 if( offset.x() < -sight_points || offset.x() > sight_points ||
626 offset.y() < -sight_points || offset.y() > sight_points ) {
627 // Outside maximum sight range
628 return false;
629 }
630
631 // TODO: fix point types
632 const std::vector<tripoint> line = line_to( ompos.raw(), omt.raw(), 0, 0 );
633 for( size_t i = 0; i < line.size() && sight_points >= 0; i++ ) {
634 const tripoint &pt = line[i];
635 const oter_id &ter = overmap_buffer.ter( tripoint_abs_omt( pt ) );
636 sight_points -= static_cast<int>( ter->get_see_cost() );
637 if( sight_points < 0 ) {
638 return false;
639 }
640 }
641 return true;
642}
constexpr auto & x()
Definition: coordinates.h:118
constexpr Point & raw()
Definition: coordinates.h:111
constexpr auto & y()
Definition: coordinates.h:124
constexpr auto xy() const
Definition: coordinates.h:130
std::vector< coords::coord_point< Point, Origin, Scale > > line_to(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:548
constexpr scale omt
Definition: coordinates.h:32
unsigned char get_see_cost() const
Definition: omdata.h:230

References oter_t::get_see_cost(), global_omt_location(), line(), line_to(), coords::omt, overmap_buffer, coords::coord_point< Point, Origin, Scale >::raw(), overmapbuffer::ter(), coords::coord_point< Point, Origin, Scale >::x(), coords::coord_point< Point, Origin, Scale >::xy(), and coords::coord_point< Point, Origin, Scale >::y().

Referenced by overmap_ui::draw_ascii(), overmap_ui::draw_om_sidebar(), and overmap_ui::draw_overmap_chunk().

◆ overmap_sight_range()

int Character::overmap_sight_range ( int  light_level) const

Returns the distance the player can see on the overmap.

Definition at line 644 of file character.cpp.

645{
646 int sight = sight_range( light_level );
647 if( sight < SEEX ) {
648 return 0;
649 }
650 if( sight <= SEEX * 4 ) {
651 return ( sight / ( SEEX / 2 ) );
652 }
653
654 sight = 6;
655 // The higher your perception, the farther you can see.
656 sight += static_cast<int>( get_per() / 2 );
657 // The higher up you are, the farther you can see.
658 sight += std::max( 0, posz() ) * 2;
659 // Mutations like Scout and Topographagnosia affect how far you can see.
660 sight += mutation_value( "overmap_sight" );
661
662 float multiplier = mutation_value( "overmap_multiplier" );
663 // Binoculars double your sight range.
664 const bool has_optic = ( has_item_with_flag( "ZOOM" ) || has_bionic( bio_eye_optic ) ||
665 ( is_mounted() &&
666 mounted_creature->has_flag( MF_MECH_RECON_VISION ) ) );
667 if( has_optic ) {
668 multiplier += 1;
669 }
670
671 sight = std::round( sight * multiplier );
672 return std::max( sight, 3 );
673}
static const bionic_id bio_eye_optic("bio_eye_optic")
int sight_range(int light_level) const override
Returns the player's sight range.
Definition: character.cpp:592
static constexpr int SEEX
@ MF_MECH_RECON_VISION
Definition: mtype.h:117

References bio_eye_optic, get_per(), has_bionic(), has_item_with_flag(), is_mounted(), MF_MECH_RECON_VISION, mounted_creature, mutation_value(), posz(), SEEX, and sight_range().

Referenced by overmap_ui::draw_ascii(), overmap_ui::draw_om_sidebar(), overmap_ui::draw_overmap_chunk(), and game::update_overmap_seen().

◆ passive_absorb_hit()

void Character::passive_absorb_hit ( const bodypart_id bp,
damage_unit du 
) const

Check for relevant passive, non-clothing that can absorb damage, and reduce by specified damage unit.

Only flat bonuses are checked here. Multiplicative ones are checked in player::absorb_hit. The damage amount will never be reduced to less than 0. This is called from player::absorb_hit

Definition at line 7871 of file character.cpp.

7872{
7873 // >0 check because some mutations provide negative armor
7874 // Thin skin check goes before subdermal armor plates because SUBdermal
7875 if( du.amount > 0.0f ) {
7876 // HACK: Get rid of this as soon as CUT and STAB are split
7877 if( du.type == DT_STAB ) {
7878 damage_unit du_copy = du;
7879 du_copy.type = DT_CUT;
7880 du.amount -= mutation_armor( bp, du_copy );
7881 } else {
7882 du.amount -= mutation_armor( bp, du );
7883 }
7884 }
7885 du.amount -= bionic_armor_bonus( bp, du.type ); //Check for passive armor bionics
7886 du.amount -= mabuff_armor_bonus( du.type );
7887 du.amount = std::max( 0.0f, du.amount );
7888}
int mabuff_armor_bonus(damage_type type) const
Returns the armor bonus against given type from martial arts buffs.
float bionic_armor_bonus(const bodypart_id &bp, damage_type dt) const
Check for passive bionics that provide armor, and returns the armor bonus This is called from player:...
Definition: character.cpp:8178

References damage_unit::amount, bionic_armor_bonus(), DT_CUT, DT_STAB, mabuff_armor_bonus(), mutation_armor(), and damage_unit::type.

Referenced by absorb_hit(), and character_funcs::is_bp_immune_to().

◆ passive_power_gen()

void Character::passive_power_gen ( bionic bio)

Passively produce power from PERPETUAL fuel.

Definition at line 1311 of file bionics.cpp.

1312{
1313 const float passive_fuel_efficiency = bio.info().passive_fuel_efficiency;
1314 if( bio.info().fuel_opts.empty() || bio.is_this_fuel_powered( fuel_type_muscle ) ||
1315 passive_fuel_efficiency == 0.0 ) {
1316 return;
1317 }
1318 const float effective_passive_efficiency = get_effective_efficiency( bio, passive_fuel_efficiency );
1319 const std::vector<itype_id> &fuel_available = get_fuel_available( bio.id );
1320 map &here = get_map();
1321
1322 for( const itype_id &fuel : fuel_available ) {
1323 const item &tmp_fuel = item( fuel );
1324 const int fuel_energy = tmp_fuel.fuel_energy();
1325 if( !tmp_fuel.has_flag( flag_PERPETUAL ) ) {
1326 continue;
1327 }
1328
1329 if( fuel == fuel_type_sun_light ) {
1330 const double modifier = g->natural_light_level( pos().z ) / default_daylight_level();
1331 mod_power_level( units::from_kilojoule( fuel_energy ) * modifier * effective_passive_efficiency );
1332 } else if( fuel == fuel_type_wind ) {
1333 int vehwindspeed = 0;
1334 const optional_vpart_position vp = here.veh_at( pos() );
1335 if( vp ) {
1336 // vehicle velocity in mph
1337 vehwindspeed = std::abs( vp->vehicle().velocity / 100 );
1338 }
1340 const double windpower = get_local_windpower( weather.windspeed + vehwindspeed,
1341 overmap_buffer.ter( global_omt_location() ), pos(), weather.winddirection,
1342 g->is_sheltered( pos() ) );
1343 mod_power_level( units::from_kilojoule( fuel_energy ) * windpower * effective_passive_efficiency );
1344 } else {
1345 mod_power_level( units::from_kilojoule( fuel_energy ) * effective_passive_efficiency );
1346 }
1347
1348 heat_emission( bio, fuel_energy );
1349 if( bio.info().power_gen_emission ) {
1350 here.emit_field( pos(), bio.info().power_gen_emission );
1351 }
1352 }
1353}
float passive_fuel_efficiency
Fraction of fuel energy passively converted to bionic power.
Definition: bionics.h:71

References default_daylight_level(), map::emit_field(), flag_PERPETUAL(), units::from_kilojoule(), item::fuel_energy(), bionic_data::fuel_opts, fuel_type_muscle, fuel_type_sun_light, fuel_type_wind, g, get_effective_efficiency(), get_fuel_available(), get_local_windpower(), get_map(), get_weather(), global_omt_location(), item::has_flag(), heat_emission(), bionic::id, bionic::info(), bionic::is_this_fuel_powered(), mod_power_level(), overmap_buffer, bionic_data::passive_fuel_efficiency, pos(), bionic_data::power_gen_emission, overmapbuffer::ter(), and map::veh_at().

Referenced by process_bionic().

◆ perform_install()

void Character::perform_install ( bionic_id  bid,
bionic_id  upbid,
int  difficulty,
int  success,
int  pl_skill,
const std::string &  installer_name,
const std::vector< trait_id > &  trait_to_rem 
)

Success or failure of installation happens here.

Definition at line 2310 of file bionics.cpp.

2313{
2314
2315 g->events().send<event_type::installs_cbm>( getID(), bid );
2316 if( upbid != bionic_id( "" ) ) {
2317 remove_bionic( upbid );
2318 //~ %1$s - name of the bionic to be upgraded (inferior), %2$s - name of the upgraded bionic (superior).
2319 add_msg( m_good, _( "Upgraded %1$s to %2$s." ),
2320 upbid.obj().name, bid.obj().name );
2321 } else {
2322 //~ %s - name of the bionic.
2323 add_msg( m_good, _( "Installed %s." ), bid.obj().name );
2324 }
2325
2326 add_bionic( bid );
2327
2328 if( !trait_to_rem.empty() ) {
2329 for( const trait_id &tid : trait_to_rem ) {
2330 if( has_trait( tid ) ) {
2331 remove_mutation( tid );
2332 }
2333 }
2334 }
2335 if( success <= 0 ) {
2336 g->events().send<event_type::fails_to_install_cbm>( getID(), bid );
2337
2338 // for chance_of_success calculation, shift skill down to a float between ~0.4 - 30
2339 float adjusted_skill = static_cast<float>( pl_skill ) - std::min( static_cast<float>( 40 ),
2340 static_cast<float>( pl_skill ) - static_cast<float>( pl_skill ) / static_cast<float>
2341 ( 10.0 ) );
2342 bionics_install_failure( installer_name, difficulty, success, adjusted_skill );
2343 }
2344 get_map().invalidate_map_cache( g->get_levz() );
2345}
void remove_bionic(const bionic_id &b)
Removes a bionic from my_bionics[].
Definition: bionics.cpp:2573
void bionics_install_failure(const std::string &installer, int difficulty, int success, float adjusted_skill)
Definition: bionics.cpp:2387
void invalidate_map_cache(const int zlev)
Definition: map.h:470
@ fails_to_install_cbm

References _, add_bionic(), add_msg(), bionic_id, bionics_install_failure(), fails_to_install_cbm, g, get_map(), getID(), has_trait(), installs_cbm, map::invalidate_map_cache(), m_good, bionic_data::name, string_id< T >::obj(), remove_bionic(), remove_mutation(), and behavior::success.

Referenced by install_bionics(), and activity_handlers::operation_do_turn().

◆ perform_special_attacks()

void Character::perform_special_attacks ( Creature t,
dealt_damage_instance dealt_dam 
)

Performs special attacks and their effects (poisonous, stinger, etc.)

Definition at line 1790 of file melee.cpp.

1791{
1792 std::vector<special_attack> special_attacks = mutation_attacks( t );
1793
1794 bool practiced = false;
1795 for( const auto &att : special_attacks ) {
1796 if( t.is_dead_state() ) {
1797 break;
1798 }
1799
1800 // TODO: Make this hit roll use unarmed skill, not weapon skill + weapon to_hit
1801 int hit_spread = t.deal_melee_attack( this, hit_roll() * 0.8 );
1802 if( hit_spread >= 0 ) {
1803 t.deal_melee_hit( this, hit_spread, false, att.damage, dealt_dam );
1804 if( !practiced ) {
1805 // Practice unarmed, at most once per combo
1806 practiced = true;
1807 as_player()->practice( skill_unarmed, rng( 0, 10 ) );
1808 }
1809 }
1810 int dam = dealt_dam.total_damage();
1811 if( dam > 0 ) {
1812 player_hit_message( this, att.text, t, dam );
1813 }
1814 }
1815}
std::vector< special_attack > mutation_attacks(Creature &t) const
Returns a vector of valid mutation attacks.
Definition: melee.cpp:1961

References Creature::as_player(), Creature::deal_melee_attack(), Creature::deal_melee_hit(), hit_roll(), Creature::is_dead_state(), mutation_attacks(), player_hit_message(), practice(), rng(), skill_unarmed, and dealt_damage_instance::total_damage().

Referenced by melee_attack().

◆ perform_technique()

void Character::perform_technique ( const ma_technique technique,
Creature t,
damage_instance di,
int &  move_cost 
)
Intelligence slightly increases chance to learn techniques when using CQB bionic

Definition at line 1369 of file melee.cpp.

1371{
1372 add_msg( m_debug, "dmg before tec:" );
1373 print_damage_info( di );
1374
1375 for( damage_unit &du : di.damage_units ) {
1376 // TODO: Allow techniques to add more damage types to attacks
1377 if( du.amount <= 0 ) {
1378 continue;
1379 }
1380
1381 du.amount += technique.damage_bonus( *this, du.type );
1382 du.damage_multiplier *= technique.damage_multiplier( *this, du.type );
1383 du.res_pen += technique.armor_penetration( *this, du.type );
1384 }
1385
1386 add_msg( m_debug, "dmg after tec:" );
1387 print_damage_info( di );
1388
1389 move_cost *= technique.move_cost_multiplier( *this );
1390 move_cost += technique.move_cost_penalty( *this );
1391
1392 if( technique.down_dur > 0 ) {
1393 t.add_effect( effect_downed, rng( 1_turns, time_duration::from_turns( technique.down_dur ) ) );
1395 if( bash.amount > 0 ) {
1396 bash.amount += 3;
1397 }
1398 }
1399
1400 if( technique.side_switch ) {
1401 const tripoint b = t.pos();
1402 int newx;
1403 int newy;
1404
1405 if( b.x > posx() ) {
1406 newx = posx() - 1;
1407 } else if( b.x < posx() ) {
1408 newx = posx() + 1;
1409 } else {
1410 newx = b.x;
1411 }
1412
1413 if( b.y > posy() ) {
1414 newy = posy() - 1;
1415 } else if( b.y < posy() ) {
1416 newy = posy() + 1;
1417 } else {
1418 newy = b.y;
1419 }
1420
1421 const tripoint &dest = tripoint( newx, newy, b.z );
1422 if( g->is_empty( dest ) ) {
1423 t.setpos( dest );
1424 }
1425 }
1426
1427 if( technique.stun_dur > 0 && !technique.powerful_knockback ) {
1428 t.add_effect( effect_stunned, rng( 1_turns, time_duration::from_turns( technique.stun_dur ) ) );
1429 }
1430
1431 if( technique.knockback_dist ) {
1432 const tripoint prev_pos = t.pos(); // track target startpoint for knockback_follow
1433 const int kb_offset_x = rng( -technique.knockback_spread, technique.knockback_spread );
1434 const int kb_offset_y = rng( -technique.knockback_spread, technique.knockback_spread );
1435 tripoint kb_point( posx() + kb_offset_x, posy() + kb_offset_y, posz() );
1436 for( int dist = rng( 1, technique.knockback_dist ); dist > 0; dist-- ) {
1437 t.knock_back_from( kb_point );
1438 }
1439 // This technique makes the player follow into the tile the target was knocked from
1440 if( technique.knockback_follow ) {
1441 const optional_vpart_position vp0 = g->m.veh_at( pos() );
1442 vehicle *const veh0 = veh_pointer_or_null( vp0 );
1443 bool to_swimmable = g->m.has_flag( "SWIMMABLE", prev_pos );
1444 bool to_deepwater = g->m.has_flag( TFLAG_DEEP_WATER, prev_pos );
1445
1446 // Check if it's possible to move to the new tile
1447 bool move_issue =
1448 g->is_dangerous_tile( prev_pos ) || // Tile contains fire, etc
1449 ( to_swimmable && to_deepwater ) || // Dive into deep water
1450 is_mounted() ||
1451 ( veh0 != nullptr && std::abs( veh0->velocity ) > 100 ) || // Diving from moving vehicle
1452 ( veh0 != nullptr && veh0->player_in_control( g->u ) ) || // Player is driving
1454
1455 if( !move_issue ) {
1456 if( t.pos() != prev_pos ) {
1457 g->place_player( prev_pos );
1458 g->on_move_effects();
1459 }
1460 }
1461 }
1462 }
1463
1464 player *p = dynamic_cast<player *>( &t );
1465
1466 if( technique.take_weapon && !has_weapon() && p != nullptr && p->is_armed() ) {
1467 if( p->is_player() ) {
1468 add_msg_if_npc( _( "<npcname> disarms you and takes your weapon!" ) );
1469 } else {
1470 add_msg_player_or_npc( _( "You disarm %s and take their weapon!" ),
1471 _( "<npcname> disarms %s and takes their weapon!" ),
1472 p->name );
1473 }
1474 item it = p->remove_weapon();
1475 wield( it );
1476 }
1477
1478 if( technique.disarms && p != nullptr && p->is_armed() ) {
1479 g->m.add_item_or_charges( p->pos(), p->remove_weapon() );
1480 if( p->is_player() ) {
1481 add_msg_if_npc( _( "<npcname> disarms you!" ) );
1482 } else {
1483 add_msg_player_or_npc( _( "You disarm %s!" ),
1484 _( "<npcname> disarms %s!" ),
1485 p->name );
1486 }
1487 }
1488
1489 //AOE attacks, feel free to skip over this lump
1490 if( !technique.aoe.empty() ) {
1491 // Remember out moves and stamina
1492 // We don't want to consume them for every attack!
1493 const int temp_moves = moves;
1494 const int temp_stamina = get_stamina();
1495
1496 std::vector<Creature *> targets;
1497
1498 valid_aoe_technique( t, technique, targets );
1499
1500 //hit only one valid target (pierce through doesn't spread out)
1501 if( technique.aoe == "impale" ) {
1502 // TODO: what if targets is empty
1503 Creature *const v = random_entry( targets );
1504 targets.clear();
1505 targets.push_back( v );
1506 }
1507
1508 //hit the targets in the lists (all candidates if wide or burst, or just the unlucky sod if deep)
1509 int count_hit = 0;
1510 for( Creature *const c : targets ) {
1511 melee_attack( *c, false );
1512 }
1513
1514 t.add_msg_if_player( m_good, vgettext( "%d enemy hit!", "%d enemies hit!", count_hit ), count_hit );
1515 // Extra attacks are free of charge (otherwise AoE attacks would SUCK)
1516 moves = temp_moves;
1517 set_stamina( temp_stamina );
1518 }
1519
1520 //player has a very small chance, based on their intelligence, to learn a style whilst using the CQB bionic
1521 if( has_active_bionic( bio_cqb ) && !martial_arts_data->knows_selected_style() ) {
1522 /** @EFFECT_INT slightly increases chance to learn techniques when using CQB bionic */
1523 // Enhanced Memory Banks bionic doubles chance to learn martial art
1524 const int bionic_boost = has_active_bionic( bionic_id( bio_memory ) ) ? 2 : 1;
1525 if( one_in( ( 1400 - ( get_int() * 50 ) ) / bionic_boost ) ) {
1526 martial_arts_data->learn_current_style_CQB( is_player() );
1527 }
1528 }
1529}
bool valid_aoe_technique(Creature &t, const ma_technique &technique)
Check if an area-of-effect technique has valid targets.
Definition: melee.cpp:1220
bool has_weapon() const override
virtual void setpos(const tripoint &pos)=0
void knock_back_from(const tripoint &p)
Definition: creature.cpp:1891
int knockback_dist
Definition: martialarts.h:98
std::string aoe
Definition: martialarts.h:101
float armor_penetration(const Character &u, damage_type type) const
float damage_multiplier(const Character &u, damage_type type) const
bool side_switch
Definition: martialarts.h:89
float damage_bonus(const Character &u, damage_type type) const
float move_cost_multiplier(const Character &u) const
float move_cost_penalty(const Character &u) const
bool take_weapon
Definition: martialarts.h:106
bool knockback_follow
Definition: martialarts.h:102
bool powerful_knockback
Definition: martialarts.h:100
float knockback_spread
Definition: martialarts.h:99
bool player_in_control(const Character &p) const
Definition: vehicle.cpp:278
int velocity
Definition: vehicle.h:1943
static const efftype_id effect_downed("downed")
static const bionic_id bio_memory("bio_memory")
static void print_damage_info(const damage_instance &di)
Definition: melee.cpp:1352
static damage_unit & get_damage_unit(std::vector< damage_unit > &di, const damage_type dt)
Definition: melee.cpp:1340
static const efftype_id effect_stunned("stunned")
static const efftype_id effect_amigara("amigara")
float damage_multiplier
Definition: damage.h:40
float res_pen
Definition: damage.h:38
vehicle * veh_pointer_or_null(const optional_vpart_position &p)

References _, Creature::add_effect(), add_msg(), Creature::add_msg_if_npc(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), damage_unit::amount, ma_technique::aoe, ma_technique::armor_penetration(), b, spell_effect::bash(), bio_cqb, bio_memory, bionic_id, c, ma_technique::damage_bonus(), damage_unit::damage_multiplier, ma_technique::damage_multiplier(), damage_instance::damage_units, ma_technique::disarms, ma_technique::down_dur, DT_BASH, effect_amigara, effect_downed, effect_stunned, time_duration::from_turns(), g, get_damage_unit(), get_int(), get_stamina(), has_active_bionic(), Creature::has_effect(), has_weapon(), is_armed(), is_mounted(), Creature::is_player(), player::is_player(), Creature::knock_back_from(), ma_technique::knockback_dist, ma_technique::knockback_follow, ma_technique::knockback_spread, m_debug, m_good, martial_arts_data, melee_attack(), move_cost(), ma_technique::move_cost_multiplier(), ma_technique::move_cost_penalty(), Creature::moves, name, one_in(), vehicle::player_in_control(), Creature::pos(), pos(), posx(), posy(), posz(), ma_technique::powerful_knockback, print_damage_info(), random_entry(), remove_weapon(), damage_unit::res_pen, rng(), set_stamina(), Creature::setpos(), ma_technique::side_switch, ma_technique::stun_dur, ma_technique::take_weapon, TFLAG_DEEP_WATER, damage_unit::type, valid_aoe_technique(), veh_pointer_or_null(), vehicle::velocity, vgettext(), and wield().

Referenced by melee_attack().

◆ perform_uninstall()

void Character::perform_uninstall ( bionic_id  bid,
int  difficulty,
int  success,
const units::energy power_lvl,
int  pl_skill 
)

Succes or failure of removal happens here.

Definition at line 2044 of file bionics.cpp.

2046{
2047 map &here = get_map();
2048 if( success > 0 ) {
2049 g->events().send<event_type::removes_cbm>( getID(), bid );
2050
2051 // until bionics can be flagged as non-removable
2052 add_msg_player_or_npc( m_neutral, _( "Your parts are jiggled back into their familiar places." ),
2053 _( "<npcname>'s parts are jiggled back into their familiar places." ) );
2054 add_msg( m_good, _( "Successfully removed %s." ), bid.obj().name );
2055 remove_bionic( bid );
2056
2057 // remove power bank provided by bionic
2058 mod_max_power_level( -power_lvl );
2059
2061 if( bid->itype().is_valid() ) {
2062 cbm = item( bid.c_str() );
2063 }
2064 cbm.faults.emplace( fault_bionic_nonsterile );
2065 here.add_item( pos(), cbm );
2066 } else {
2067 g->events().send<event_type::fails_to_remove_cbm>( getID(), bid );
2068 // for chance_of_success calculation, shift skill down to a float between ~0.4 - 30
2069 float adjusted_skill = static_cast<float>( pl_skill ) - std::min( static_cast<float>( 40 ),
2070 static_cast<float>( pl_skill ) - static_cast<float>( pl_skill ) / static_cast<float>
2071 ( 10.0 ) );
2072 bionics_uninstall_failure( difficulty, success, adjusted_skill );
2073
2074 }
2075 here.invalidate_map_cache( g->get_levz() );
2076}
static const fault_id fault_bionic_nonsterile("fault_bionic_nonsterile")
static const itype_id itype_burnt_out_bionic("burnt_out_bionic")
void bionics_uninstall_failure(int difficulty, int success, float adjusted_skill)
When a player fails the surgery.
Definition: bionics.cpp:1731
item & add_item(const tripoint &p, item new_item)
Place an item on the map, despite the parameter name, this is not necessarily a new item.
Definition: map.cpp:4336
@ fails_to_remove_cbm

References _, map::add_item(), add_msg(), Creature::add_msg_player_or_npc(), bionics_uninstall_failure(), string_id< T >::c_str(), fails_to_remove_cbm, fault_bionic_nonsterile, item::faults, g, get_map(), getID(), map::invalidate_map_cache(), string_id< T >::is_valid(), bionic_data::itype(), itype_burnt_out_bionic, m_good, m_neutral, mod_max_power_level(), bionic_data::name, string_id< T >::obj(), pos(), remove_bionic(), removes_cbm, and behavior::success.

Referenced by activity_handlers::operation_do_turn(), and uninstall_bionic().

◆ pick_name()

void Character::pick_name ( bool  bUseDefault = false)

Returns a random name from NAMES_*.

Definition at line 129 of file newcharacter.cpp.

130{
131 if( bUseDefault && !get_option<std::string>( "DEF_CHAR_NAME" ).empty() ) {
132 name = get_option<std::string>( "DEF_CHAR_NAME" );
133 } else {
135 }
136}
std::string generate(bool is_male)
Return a random full name given gender.
Definition: name.cpp:128

References Name::generate(), male, and name.

Referenced by avatar::randomize(), npc::randomize(), and set_description().

◆ pick_technique()

matec_id Character::pick_technique ( Creature t,
const item weap,
bool  crit,
bool  dodge_counter,
bool  block_counter 
)

Returns a random valid technique.

Definition at line 1117 of file melee.cpp.

1119{
1120
1121 const std::vector<matec_id> all = martial_arts_data->get_all_techniques( weap );
1122
1123 std::vector<matec_id> possible;
1124
1125 bool downed = t.has_effect( effect_downed );
1126 bool stunned = t.has_effect( effect_stunned );
1127 bool wall_adjacent = g->m.is_wall_adjacent( pos() );
1128
1129 // first add non-aoe tecs
1130 for( const matec_id &tec_id : all ) {
1131 const ma_technique &tec = tec_id.obj();
1132
1133 // ignore "dummy" techniques like WBLOCK_1
1134 if( tec.dummy ) {
1135 continue;
1136 }
1137
1138 // skip defensive techniques
1139 if( tec.defensive ) {
1140 continue;
1141 }
1142
1143 // skip wall adjacent techniques if not next to a wall
1144 if( tec.wall_adjacent && !wall_adjacent ) {
1145 continue;
1146 }
1147
1148 // skip dodge counter techniques
1149 if( dodge_counter != tec.dodge_counter ) {
1150 continue;
1151 }
1152
1153 // skip block counter techniques
1154 if( block_counter != tec.block_counter ) {
1155 continue;
1156 }
1157
1158 // if critical then select only from critical tecs
1159 // but allow the technique if its crit ok
1160 if( !tec.crit_ok && ( crit != tec.crit_tec ) ) {
1161 continue;
1162 }
1163
1164 // don't apply downing techniques to someone who's already downed
1165 if( downed && tec.down_dur > 0 ) {
1166 continue;
1167 }
1168
1169 // don't apply "downed only" techniques to someone who's not downed
1170 if( !downed && tec.downed_target ) {
1171 continue;
1172 }
1173
1174 // don't apply "stunned only" techniques to someone who's not stunned
1175 if( !stunned && tec.stunned_target ) {
1176 continue;
1177 }
1178
1179 // don't apply disarming techniques to someone without a weapon
1180 // TODO: these are the stat requirements for tec_disarm
1181 // dice( dex_cur + get_skill_level("unarmed"), 8) >
1182 // dice(p->dex_cur + p->get_skill_level("melee"), 10))
1183 if( tec.disarms && !t.has_weapon() ) {
1184 continue;
1185 }
1186
1187 if( ( tec.take_weapon && ( has_weapon() || !t.has_weapon() ) ) ) {
1188 continue;
1189 }
1190
1191 // Don't apply humanoid-only techniques to non-humanoids
1192 if( tec.human_target && !t.in_species( HUMAN ) ) {
1193 continue;
1194 }
1195 // if aoe, check if there are valid targets
1196 if( !tec.aoe.empty() && !valid_aoe_technique( t, tec ) ) {
1197 continue;
1198 }
1199
1200 // If we have negative weighting then roll to see if it's valid this time
1201 if( tec.weighting < 0 && !one_in( std::abs( tec.weighting ) ) ) {
1202 continue;
1203 }
1204
1205 if( tec.is_valid_character( *this ) ) {
1206 possible.push_back( tec.id );
1207
1208 //add weighted options into the list extra times, to increase their chance of being selected
1209 if( tec.weighting > 1 ) {
1210 for( int i = 1; i < tec.weighting; i++ ) {
1211 possible.push_back( tec.id );
1212 }
1213 }
1214 }
1215 }
1216
1217 return random_entry( possible, tec_none );
1218}
virtual bool in_species(const species_id &) const
Definition: creature.cpp:971
bool stunned_target
Definition: martialarts.h:117
bool defensive
Definition: martialarts.h:88
bool human_target
Definition: martialarts.h:119
bool block_counter
Definition: martialarts.h:108
bool wall_adjacent
Definition: martialarts.h:118
bool dodge_counter
Definition: martialarts.h:107
bool downed_target
Definition: martialarts.h:116
static const species_id HUMAN("HUMAN")
const std::array< type, 4 > all
For the purposes of iteration.
Definition: om_direction.h:26

References om_direction::all, ma_technique::aoe, ma_technique::block_counter, ma_technique::crit_ok, ma_technique::crit_tec, ma_technique::defensive, ma_technique::disarms, ma_technique::dodge_counter, ma_technique::down_dur, ma_technique::downed_target, ma_technique::dummy, effect_downed, effect_stunned, g, Creature::has_effect(), Creature::has_weapon(), has_weapon(), HUMAN, ma_technique::human_target, ma_technique::id, Creature::in_species(), ma_technique::is_valid_character(), martial_arts_data, one_in(), pos(), random_entry(), ma_technique::stunned_target, ma_technique::take_weapon, tec_none, valid_aoe_technique(), ma_technique::wall_adjacent, and ma_technique::weighting.

Referenced by block_hit(), melee_attack(), and on_dodge().

◆ place_corpse() [1/2]

void Character::place_corpse ( )

Definition at line 10083 of file character.cpp.

10084{
10085 //If the character/NPC is on a distant mission, don't drop their their gear when they die since they still have a local pos
10086 if( !death_drops ) {
10087 return;
10088 }
10089 std::vector<item *> tmp = inv_dump();
10091 map &here = get_map();
10092 for( auto itm : tmp ) {
10093 here.add_item_or_charges( pos(), *itm );
10094 }
10095 for( const bionic &bio : *my_bionics ) {
10096 if( bio.info().itype().is_valid() ) {
10097 item cbm( bio.id.str(), calendar::turn );
10098 cbm.faults.emplace( fault_bionic_nonsterile );
10099 body.components.push_back( cbm );
10100 }
10101 }
10102
10103 // Restore amount of installed pseudo-modules of Power Storage Units
10104 std::pair<int, int> storage_modules = amount_of_storage_bionics();
10105 for( int i = 0; i < storage_modules.first; ++i ) {
10107 cbm.faults.emplace( fault_bionic_nonsterile );
10108 body.components.push_back( cbm );
10109 }
10110 for( int i = 0; i < storage_modules.second; ++i ) {
10112 cbm.faults.emplace( fault_bionic_nonsterile );
10113 body.components.push_back( cbm );
10114 }
10115 here.add_item_or_charges( pos(), body );
10116}
static const itype_id itype_power_storage("bio_power_storage")
static const fault_id fault_bionic_nonsterile("fault_bionic_nonsterile")
static const itype_id itype_power_storage_mkII("bio_power_storage_mkII")
bool death_drops
Definition: character.h:244
std::pair< int, int > amount_of_storage_bionics() const
Returns amount of Storage CBMs in the corpse.
Definition: bionics.cpp:2615
std::map< bodypart_str_id, bodypart > body
this is the actual body of the creature
Definition: creature.h:498
static item make_corpse(const mtype_id &mt=string_id< mtype >::NULL_ID(), time_point turn=calendar::turn, const std::string &name="", int upgrade_time=-1)
Make a corpse of the given monster type.
Definition: item.cpp:507

References map::add_item_or_charges(), amount_of_storage_bionics(), Creature::body, death_drops, fault_bionic_nonsterile, item::faults, get_map(), inv_dump(), itype_power_storage, itype_power_storage_mkII, item::make_corpse(), my_bionics, name, string_id< mtype >::NULL_ID(), pos(), and calendar::turn.

Referenced by npc::die(), game::handle_action(), and game::is_game_over().

◆ place_corpse() [2/2]

void Character::place_corpse ( const tripoint_abs_omt om_target)

Definition at line 10118 of file character.cpp.

10119{
10120 tinymap bay;
10121 bay.load( project_to<coords::sm>( om_target ), false );
10122 point fin{ rng( 1, SEEX * 2 - 2 ), rng( 1, SEEX * 2 - 2 ) };
10123 // This makes no sense at all. It may find a random tile without furniture, but
10124 // if the first try to find one fails, it will go through all tiles of the map
10125 // and essentially select the last one that has no furniture.
10126 // Q: Why check for furniture? (Check for passable or can-place-items seems more useful.)
10127 // Q: Why not grep a random point out of all the possible points (e.g. via random_entry)?
10128 // Q: Why use furn_str_id instead of f_null?
10129 // TODO: fix it, see above.
10130 if( bay.furn( fin ) != furn_str_id( "f_null" ) ) {
10131 for( const tripoint &p : bay.points_on_zlevel() ) {
10132 if( bay.furn( p ) == furn_str_id( "f_null" ) ) {
10133 fin.x = p.x;
10134 fin.y = p.y;
10135 }
10136 }
10137 }
10138
10139 std::vector<item *> tmp = inv_dump();
10141 for( auto itm : tmp ) {
10142 bay.add_item_or_charges( fin, *itm );
10143 }
10144 for( const bionic &bio : *my_bionics ) {
10145 if( bio.info().itype().is_valid() ) {
10146 body.put_in( item( bio.info().itype(), calendar::turn ) );
10147 }
10148 }
10149
10150 // Restore amount of installed pseudo-modules of Power Storage Units
10151 std::pair<int, int> storage_modules = amount_of_storage_bionics();
10152 for( int i = 0; i < storage_modules.first; ++i ) {
10153 body.put_in( item( "bio_power_storage" ) );
10154 }
10155 for( int i = 0; i < storage_modules.second; ++i ) {
10156 body.put_in( item( "bio_power_storage_mkII" ) );
10157 }
10158 bay.add_item_or_charges( fin, body );
10159}
tripoint_range< tripoint > points_on_zlevel() const
Yields a range of all points that are contained in the map and have the z-level of this map (abs_sub)...
Definition: map.cpp:8642
void load(const tripoint &w, bool update_vehicles, bool pump_events=false)
Load submaps into grid.
Definition: map.cpp:6625
Definition: map.h:2109

References map::add_item_or_charges(), amount_of_storage_bionics(), Creature::body, map::furn(), inv_dump(), map::load(), item::make_corpse(), my_bionics, name, string_id< mtype >::NULL_ID(), map::points_on_zlevel(), rng(), SEEX, and calendar::turn.

◆ pos()

const tripoint & Character::pos ( ) const
overridevirtual

Implements Creature.

Definition at line 587 of file character.cpp.

588{
589 return position;
590}

References position.

Referenced by absorb_hit(), iuse::acidbomb_act(), activate_bionic(), npc::activate_item(), activate_mutation(), enchantment::activate_passive(), activity_on_turn_move_loot(), map::add_field(), add_known_trap(), inventory_selector::add_nearby_items(), npc::address_player(), npc::alt_attack(), map::apparent_light_helper(), map::apply_character_light(), apply_persistent_morale(), iuse::artifact(), npc::assess_danger(), assign_activity(), activity_handlers::atm_do_turn(), Creature::auto_find_hostile_target(), game::autopilot_vehicles(), npc::avoid_friendly_fire(), avoid_trap(), iuse::bell(), best_nearby_lifting_assist(), mattack::bio_op_disarm(), blossoms(), iuse::boltcutters(), map::build_vision_transparency_cache(), burn_fuel(), iuse::burrow(), game::butcher(), activity_handlers::butcher_finish(), butchery_drops_harvest(), butchery_quarter(), set_transformed_iuse::bypass(), iuse::cable_attach(), calc_needs_rates(), calculate_aim_cap(), calculate_dispersion(), iuse::call_of_tindalos(), iuse::camera(), player::can_continue_craft(), can_examine_at(), can_hear(), can_mount(), npc::can_move_to(), character_funcs::can_see_fine_details(), iuse_transform::can_use(), firestarter_actor::can_use(), iuse::capture_monster_act(), iexamine::cardreader_foodplace(), enchantment::cast_enchantment_spell(), iexamine::chainfence(), debug_menu::character_edit_menu(), game::chat(), check_art_charge_req(), player::check_eligible_containers_for_crafting(), vehicle::check_heli_ascend(), check_mount_is_spooked(), check_mount_will_move(), npc::check_or_use_weapon_cbm(), check_outbounds_activity(), relic_funcs::check_recharge_reqs(), iuse::chop_tree(), avatar::clear_memorized_tile(), doors::close_door(), game_menus::inv::compare(), complete_construction(), veh_interact::complete_vehicle(), consider_butchery(), consume_charges(), consume_effects(), player::consume_items(), consume_med(), consume_remote_fuel(), player::consume_tools(), game::control_vehicle(), cough(), npc::could_move_onto(), player::craft_consume_tools(), crafting_inventory(), craft_command::create_in_progress_craft(), game::create_starting_npcs(), map::creature_in_field(), game::critter_at(), iuse::crowbar(), iexamine::curtains(), iuse::cut_log_into_planks(), salvage_actor::cut_up(), deactivate_bionic(), deal_damage(), debug_menu::debug(), defer_move(), item_location::impl::item_on_map::describe(), item_location::impl::item_on_vehicle::describe(), trap::detect_trap(), npc::die(), iuse::dig(), iuse::dig_channel(), iuse::directional_antenna(), crafting::disassemble_all(), character_display::disp_info(), game::disp_NPCs(), game::display_scent(), npc::dispose_item(), npc::do_npc_read(), character_funcs::do_pause(), npc::do_pulp(), avatar::do_read(), npc::do_reload(), game::do_turn(), drop_activity_actor::do_turn(), stash_activity_actor::do_turn(), move_items_activity_actor::do_turn(), pickup_activity_actor::do_turn(), throw_activity_actor::do_turn(), iexamine::door_peephole(), game::draw(), draw_bionics_titlebar(), draw_cone_aoe_curses(), draw_env_compact(), draw_health_classic(), anonymous_namespace{animation.cpp}::draw_hit_player_curses(), game::draw_look_around_cursor(), draw_speed_tab(), game::draw_ter(), target_ui::draw_terrain_overlay(), draw_throw_aim(), draw_time_classic(), game::draw_trail_to_square(), draw_veh_compact(), draw_veh_padding(), game::drop(), drop(), drop_invalid_inventory(), npc::drop_items(), talk_function::drop_weapon(), monexamine::dump_items(), eat(), avatar_action::eat_here(), eff_fun_fungus(), eff_fun_hallu(), iuse::einktabletpc(), iexamine::elevator(), emit_radio_signal(), explosion_handler::emp_blast(), npc::enough_time_to_reload(), env_surgery_bonus(), game::examine(), craft_command::execute(), npc::execute_action(), extract_or_wreck_cbms(), npc::faction_display(), iuse::fill_pit(), character_funcs::find_ammo_items_or_mags(), find_auto_consume(), find_best_bench(), npc::find_corpse_to_pulp(), npc::find_dangerous_explosives(), npc::find_item(), activity_handlers::find_mount_do_turn(), game::find_nearby_items(), game::find_or_make_stairs(), find_remote_fuel(), character_funcs::fine_detail_vision_mod(), hacking_activity_actor::finish(), npc::finish_read(), fire(), ranged::fire_gun(), iuse::fishing_rod(), game::fling_creature(), floor_bedding_warmth(), floor_item_warmth(), floor_warmth(), iexamine::flower_marloss(), iexamine::flower_poppy(), activity_handlers::forage_finish(), forced_dismount(), fungal_effects::fungalize(), iuse::fungicide(), mattack::fungus_sprout(), iexamine::fvat_full(), activity_handlers::game_do_turn(), iuse::gasmask(), iexamine::gaspump(), iuse::geiger(), generic_multi_activity_check_requirement(), generic_multi_activity_handler(), generic_multi_activity_locations(), avatar::get_book_reader(), character_funcs::get_crafting_helpers(), game::get_dangerous_tile(), activatable_inventory_preset::get_denial(), get_dodge(), player::get_eligible_containers_for_crafting(), get_heat_radiation(), get_hostile_creatures(), get_item_location(), avatar::get_memorized_tile(), get_next_auto_move_direction(), overmap_ui::get_overmap_path_to(), npc::get_path_avoid(), get_patient(), get_temp(), game::get_veh_dir_indicator_location(), get_visible_creatures(), ranged::get_weapon_dispersion(), talk_function::give_all_aid(), npc::go_to_omt_destination(), npc::good_escape_direction(), grab(), mattack::grab_drag(), game::grabbed_furn_move(), game::grabbed_veh_move(), npc::guard_current_pos(), iuse::gun_repair(), ranged::gunmode_checks_common(), ranged::gunmode_checks_weapon(), iuse::hacksaw(), activity_handlers::hacksaw_finish(), iuse::hammer(), handbrake(), game::handle_action(), target_ui::handle_cursor_movement(), handle_harvest(), handle_melee_wear(), item::handle_pickup_ownership(), npc::handle_sound(), vehicle::handle_trap(), hardcoded_effects(), has_alarm_clock(), has_fire(), has_neighbor(), has_watch(), haul(), npc::heal_player(), npc::heal_self(), heat_emission(), iuse::honeycomb(), i_add_or_drop(), i_rem(), i_rem_keep_contents(), impact(), in_climate_control(), npc_trading::init_buying(), iexamine::intercom(), invoke_item(), npc::is_active(), enchantment::is_active(), place_trap_actor::is_allowed(), is_deaf(), is_driving(), monster::is_fleeing(), game::is_game_over(), game::is_in_viewport(), is_snuggling(), is_solid_neighbor(), ma_requirements::is_valid_character(), is_visible_in_range(), iuse::jackhammer(), monexamine::kill_zslave(), knock_back_to(), game::knockback(), knows_trap(), firestarter_actor::light_mod(), game::list_items(), game::list_monsters(), avatar_funcs::list_potential_theft_witnesses(), vehicle_prototype::load(), game::load(), avatar::load_map_memory(), aim_activity_actor::load_RAS_weapon(), activity_handlers::lockpicking_finish(), activity_handlers::longsalvage_finish(), game::look_around(), npc::look_for_player(), loot(), iuse::lumber(), ranged::make_gun_sound_effect(), activity_handlers::make_zlave_finish(), iuse::makemound(), item_action_generator::map_actions_to_items(), marloss_common(), melee_attack(), melee_special_effects(), avatar::memorize_symbol(), avatar::memorize_tile(), npc::method_of_attack(), mill_activate(), target_handler::mode_turrets(), modify_morale(), game::mon_info_update(), game::monmove(), iuse::mop(), npc::move(), avatar_action::move(), npc::move_away_from(), npc::move_to(), npc::move_to_next(), firestarter_actor::moves_cost_by_fuel(), game::moving_vehicle_dismount(), npc::mug_player(), multicooker_hallu(), mutation_effect(), npc::mutiny(), iuse::mycus(), inventory_selector::naturalize_category(), nearby(), iuse::note_bionics(), npc::npc_dismount(), game::npc_menu(), mattack::nurse_assist(), mattack::nurse_check_up(), mattack::nurse_operate(), item_location::impl::item_on_map::obtain_cost(), item_location::impl::item_on_vehicle::obtain_cost(), on_dodge(), npc::on_load(), item::on_pickup(), item::on_takeoff(), item::on_wear(), open(), map::open_door(), activity_handlers::operation_do_turn(), activity_handlers::operation_finish(), operator_present(), game::overmap_npc_move(), iuse::oxytorch(), activity_handlers::oxytorch_do_turn(), activity_handlers::oxytorch_finish(), passive_power_gen(), iexamine::pay_gas(), game::peek(), perform_technique(), perform_uninstall(), perform_zone_activity_turn(), game::phasing_move(), debug_menu::pick_character(), pick_plant(), character_funcs::pick_safe_adjacent_tile(), pick_technique(), npc::pick_up_item(), iuse::pickaxe(), game::pickup_feet(), iexamine::pit_covered(), place_and_add_as_known(), place_corpse(), npc::place_on_map(), game::place_player(), start_location::place_player(), game::place_player_overmap(), iuse::play_music(), vehicle::player_in_control(), map::player_in_field(), player_on_couch(), pldrive(), item_location::impl::item_on_person::position(), firestarter_actor::prep_firestarter_use(), npc::pretend_fire(), print_aim(), npc::print_info(), print_items(), game::process_artifact(), process_bionic(), process_effects_internal(), process_items(), relic_funcs::process_recharge_entry(), sounds::process_sound_markers(), process_turn(), prompt_disassemble_single(), activity_handlers::pry_nails_finish(), iexamine::quern_examine(), plot_options::query_seed(), avatar_action::ramp_move(), mattack::ranged_pull(), reach_attack(), npc::reach_omt_destination(), read(), recalc_speed_bonus(), ranged::recoil_vehicle(), activity_handlers::reload_finish(), vehicle::remote_controlled(), monexamine::remove_bag_from(), render_wind(), veh_utils::repair_part(), requirements_map(), firestarter_actor::resolve_firestarter_use(), iuse::robotcontrol(), iuse::robotcontrol_can_target(), rod_fish(), character_funcs::roll_can_sleep(), rooted(), rooted_message(), route_adjacent(), target_ui::run(), examine_item_menu::run(), run_cost(), avatar::save_map_memory(), npc::say(), character_funcs::search_surroundings(), npc::see_item_say_smth(), sees(), sees_with_infrared(), conditional_t< T >::set_is_driving(), set_item_inventory(), avatar::set_movement_mode(), conditional_t< T >::set_npc_role_nearby(), talk_effect_fun_t::set_u_buy_monster(), monster::setpos(), npc::setpos(), activity_handlers::shear_finish(), npc::shift(), shout(), show_armor_layers_ui(), iexamine::shrub_marloss(), sight_range(), sinkhole_safety_roll(), smash(), smoker_activate(), iexamine::smoker_options(), spawn_animal(), spawn_spores(), activity_handlers::spellcasting_finish(), spores(), standard_npc::standard_npc(), autodrive_activity_actor::start(), activity_handlers::start_fire_do_turn(), game::start_game(), npc::stow_item(), suffer_from_bad_bionics(), suffer_from_other_mutations(), suffer_from_radiation(), suffer_from_schizophrenia(), suffer_in_sunlight(), suffer_while_underwater(), game::swap_critters(), avatar_action::swim(), symbol_color(), takeoff(), iuse::talking_doll(), iuse::tazer(), ranged::throw_item(), toolweapon_off(), toolweapon_on(), iuse::tow_attach(), iexamine::trap(), activity_handlers::travel_do_turn(), npc::travel_overmap(), iexamine::tree_hickory(), iexamine::tree_maple_tapped(), iexamine::tree_marloss(), explosion_iuse::trigger_explosion(), try_consume(), avatar_funcs::try_disarm_npc(), try_fuel_fire(), game::try_get_left_click_action(), game::try_get_right_click_action(), try_reject_mutagen(), salvage_actor::try_to_cut_up(), avatar_funcs::try_to_sleep(), iuse::unfold_generic(), uninstall_bionic(), avatar_funcs::unload_item(), update_bodytemp(), update_needs(), npc::update_path(), game::update_stair_monsters(), editmap::update_view_with_help(), iuse_transform::use(), countdown_actor::use(), explosion_iuse::use(), unfold_vehicle_iuse::use(), delayed_transform_iuse::use(), set_transform_iuse::use(), set_transformed_iuse::use(), place_monster_iuse::use(), place_npc_iuse::use(), pick_lock_actor::use(), deploy_furn_actor::use(), firestarter_actor::use(), fireweapon_off_actor::use(), fireweapon_on_actor::use(), manualnoise_actor::use(), musical_instrument_actor::use(), holster_actor::use(), heal_actor::use(), place_trap_actor::use(), emit_actor::use(), mutagen_iv_actor::use(), deploy_tent_actor::use(), unpack_actor::use(), use_charges(), use_fire(), valid_aoe_technique(), game::validate_camps(), game::vertical_move(), activity_handlers::vibe_do_turn(), vomit(), iuse::vortex(), wait(), game::walk_move(), npc::warn_about(), iuse::weather_tool(), npc::wield(), avatar_action::wield(), npc::wont_hit_friend(), npc::worker_downtime(), and game::zones_manager().

◆ position_to_wear_new_item()

std::list< item >::iterator Character::position_to_wear_new_item ( const item new_item)
protected

Return the position in the worn list where new_item would be put by default.

Definition at line 3917 of file character.cpp.

3918{
3919 // By default we put this item on after the last item on the same or any
3920 // lower layer.
3921 return std::find_if(
3922 worn.rbegin(), worn.rend(),
3923 [&]( const item & w ) {
3924 return w.get_layer() <= new_item.get_layer();
3925 }
3926 ).base();
3927}

References worn.

Referenced by item_encumb(), and wear_item().

◆ posx()

◆ posy()

◆ posz()

int Character::posz ( ) const
inlineoverridevirtual

◆ pour_into() [1/2]

bool Character::pour_into ( item container,
item liquid 
)

Try to pour the given liquid into the given container/vehicle.

The transferred charges are removed from the liquid item. Check the charges of afterwards to see if anything has been transferred at all. The functions do not consume any move points.

Returns
Whether anything has been moved at all. false indicates the transfer is not possible at all. true indicates at least some of the liquid has been moved.

Definition at line 6339 of file character.cpp.

6340{
6341 std::string err;
6342 const int amount = container.get_remaining_capacity_for_liquid( liquid, *this, &err );
6343
6344 if( !err.empty() ) {
6345 add_msg_if_player( m_bad, err );
6346 return false;
6347 }
6348
6349 add_msg_if_player( _( "You pour %1$s into the %2$s." ), liquid.tname(), container.tname() );
6350
6351 container.fill_with( liquid, amount );
6352 inv.unsort();
6353
6354 if( liquid.charges > 0 ) {
6355 add_msg_if_player( _( "There's some left over!" ) );
6356 }
6357
6358 return true;
6359}
void fill_with(item &liquid, int amount=INFINITE_CHARGES)
Fill item with liquid up to its capacity.
Definition: item.cpp:8568
int get_remaining_capacity_for_liquid(const item &liquid, bool allow_bucket=false, std::string *err=nullptr) const
How much more of this liquid (in charges) can be put in this container.
Definition: item.cpp:8430

References _, Creature::add_msg_if_player(), item::charges, item::fill_with(), item::get_remaining_capacity_for_liquid(), inv, m_bad, item::tname(), and inventory::unsort().

Referenced by activity_handlers::fill_liquid_do_turn().

◆ pour_into() [2/2]

bool Character::pour_into ( vehicle veh,
item liquid 
)

Definition at line 6361 of file character.cpp.

6362{
6363 auto sel = [&]( const vehicle_part & pt ) {
6364 return pt.is_tank() && pt.can_reload( liquid );
6365 };
6366
6367 auto stack = units::legacy_volume_factor / liquid.type->stack_size;
6368 auto title = string_format( _( "Select target tank for <color_%s>%.1fL %s</color>" ),
6369 get_all_colors().get_name( liquid.color() ),
6370 round_up( to_liter( liquid.charges * stack ), 1 ),
6371 liquid.tname() );
6372
6373 auto &tank = veh_interact::select_part( veh, sel, title );
6374 if( !tank ) {
6375 return false;
6376 }
6377
6378 tank.fill_with( liquid );
6379
6380 //~ $1 - vehicle name, $2 - part name, $3 - liquid type
6381 add_msg_if_player( _( "You refill the %1$s's %2$s with %3$s." ),
6382 veh.name, tank.name(), liquid.type_name() );
6383
6384 if( liquid.charges > 0 ) {
6385 add_msg_if_player( _( "There's some left over!" ) );
6386 }
6387 return true;
6388}
double round_up(double val, unsigned int dp)
Round a value up at a given decimal place.
nc_color color() const
Returns the default color of the item (e.g.
Definition: item.cpp:4899
static vehicle_part & select_part(const vehicle &veh, const part_selector &sel, const std::string &title=std::string())
Prompt for a part matching the selector function.
std::string name
Definition: vehicle.h:1874
color_manager & get_all_colors()
Definition: color.cpp:45
std::string title(holiday current_holiday)
Definition: path_info.cpp:334
constexpr double to_liter(const volume &v)
Definition: units_volume.h:43
static constexpr volume legacy_volume_factor
Definition: units_volume.h:50
Structure, describing vehicle part (i.e., wheel, seat)
Definition: vehicle.h:186

References _, Creature::add_msg_if_player(), item::charges, item::color(), get_all_colors(), get_name(), units::legacy_volume_factor, vehicle::name, round_up(), veh_interact::select_part(), itype::stack_size, string_format(), PATH_INFO::title(), item::tname(), units::to_liter(), item::type, and item::type_name().

◆ power_rating()

float Character::power_rating ( ) const
overridevirtual

Returns an approximation of the creature's strength.

Implements Creature.

Definition at line 9926 of file character.cpp.

9927{
9928 int dmg = std::max( { weapon.damage_melee( DT_BASH ),
9931 } );
9932
9933 int ret = 2;
9934 // Small guns can be easily hidden from view
9935 if( weapon.volume() <= 250_ml ) {
9936 ret = 2;
9937 } else if( weapon.is_gun() ) {
9938 ret = 4;
9939 } else if( dmg > 12 ) {
9940 ret = 3; // Melee weapon or weapon-y tool
9941 }
9942 if( get_size() == MS_HUGE ) {
9943 ret += 1;
9944 }
9945 if( is_wearing_power_armor( nullptr ) ) {
9946 ret = 5; // No mercy!
9947 }
9948 return ret;
9949}

References item::damage_melee(), DT_BASH, DT_CUT, DT_STAB, get_size(), item::is_gun(), is_wearing_power_armor(), MS_HUGE, cata::hash64_detail::ret, item::volume(), and weapon.

◆ practice()

void Character::practice ( const skill_id id,
int  amount,
int  cap = 99,
bool  suppress_warning = false 
)

This handles giving xp for a skill.

Definition at line 3383 of file character.cpp.

3384{
3385 SkillLevel &level = get_skill_level_object( id );
3386 const Skill &skill = id.obj();
3387 std::string skill_name = skill.name();
3388
3389 if( !level.can_train() && !in_sleep_state() ) {
3390 // If leveling is disabled, don't train, don't drain focus, don't print anything
3391 // Leaving as a skill method rather than global for possible future skill cap setting
3392 return;
3393 }
3394
3395 const auto highest_skill = [&]() {
3396 std::pair<skill_id, int> result( skill_id::NULL_ID(), -1 );
3397 for( const auto &pair : *_skills ) {
3398 const SkillLevel &lobj = pair.second;
3399 if( lobj.level() > result.second ) {
3400 result = std::make_pair( pair.first, lobj.level() );
3401 }
3402 }
3403 return result.first;
3404 };
3405
3406 const bool isSavant = has_trait( trait_SAVANT );
3407 const skill_id savantSkill = isSavant ? highest_skill() : skill_id::NULL_ID();
3408
3409 amount = adjust_for_focus( amount );
3410
3411 if( has_trait( trait_PACIFIST ) && skill.is_combat_skill() ) {
3412 if( !one_in( 3 ) ) {
3413 amount = 0;
3414 }
3415 }
3416 if( has_trait_flag( "PRED2" ) && skill.is_combat_skill() ) {
3417 if( one_in( 3 ) ) {
3418 amount *= 2;
3419 }
3420 }
3421 if( has_trait_flag( "PRED3" ) && skill.is_combat_skill() ) {
3422 amount *= 2;
3423 }
3424
3425 if( has_trait_flag( "PRED4" ) && skill.is_combat_skill() ) {
3426 amount *= 3;
3427 }
3428
3429 if( isSavant && id != savantSkill ) {
3430 amount /= 2;
3431 }
3432
3433 if( amount > 0 && get_skill_level( id ) > cap ) { //blunt grinding cap implementation for crafting
3434 amount = 0;
3435 if( !suppress_warning && one_in( 5 ) ) {
3437 }
3438 }
3439 if( amount > 0 && level.isTraining() ) {
3440 int oldLevel = get_skill_level( id );
3441 get_skill_level_object( id ).train( amount );
3442 int newLevel = get_skill_level( id );
3443 if( is_player() && newLevel > oldLevel ) {
3444 add_msg( m_good, _( "Your skill in %s has increased to %d!" ), skill_name, newLevel );
3445 }
3446 if( is_player() && newLevel > cap ) {
3447 //inform player immediately that the current recipe can't be used to train further
3448 add_msg( m_info, _( "You feel that %s tasks of this level are becoming trivial." ),
3449 skill_name );
3450 }
3451
3452 int chance_to_drop = focus_pool;
3453 focus_pool -= chance_to_drop / 100;
3454 // Apex Predators don't think about much other than killing.
3455 // They don't lose Focus when practicing combat skills.
3456 if( ( rng( 1, 100 ) <= ( chance_to_drop % 100 ) ) && ( !( has_trait_flag( "PRED4" ) &&
3457 skill.is_combat_skill() ) ) ) {
3458 focus_pool--;
3459 }
3460 }
3461
3463}
static const trait_id trait_SAVANT("SAVANT")
static const trait_id trait_PACIFIST("PACIFIST")
SkillLevel & get_skill_level_object(const skill_id &ident)
Definition: character.cpp:3312
int adjust_for_focus(int amount) const
Definition: character.cpp:9889
bool can_train() const
Definition: skill.cpp:311
bool isTraining() const
Definition: skill.h:117
void practice()
Definition: skill.cpp:297
void train(int amount, bool skip_scaling=false)
Definition: skill.cpp:223
void show_skill_capped_notice(const Character &who, const skill_id &id)
This shows warning to the player that their current activity will not give them xp.

References _, _skills, add_msg(), adjust_for_focus(), SkillLevel::can_train(), focus_pool, get_skill_level(), get_skill_level_object(), has_trait(), has_trait_flag(), in_sleep_state(), Skill::is_combat_skill(), Creature::is_player(), SkillLevel::isTraining(), SkillLevel::level(), m_good, m_info, Skill::name(), string_id< Skill >::NULL_ID(), one_in(), SkillLevel::practice(), rng(), character_funcs::show_skill_capped_notice(), SkillLevel::train(), trait_PACIFIST, and trait_SAVANT.

Referenced by vehicle::act_on_map(), activity_handlers::butcher_finish(), butchery_drops_harvest(), talk_function::companion_skill_trainer(), crafting::complete_disassemble(), veh_interact::complete_vehicle(), player::craft_skill_gain(), salvage_actor::cut_up(), character_funcs::do_pause(), iuse::einktabletpc(), heal_actor::finish_using(), ranged::fire_gun(), activity_handlers::fish_do_turn(), iuse::fish_trap(), iexamine::fvat_full(), iuse::gun_repair(), hack_attempt(), computer_session::hack_attempt(), hackveh(), install_bionics(), place_trap_actor::data::load(), activity_handlers::make_zlave_finish(), melee_train(), iuse::multicooker(), on_dodge(), perform_special_attacks(), pick_plant(), vehicle::pldrive(), iexamine::practice_survival_while_foraging(), activity_handlers::pry_nails_finish(), activity_handlers::pulp_do_turn(), repair_item_actor::repair(), veh_utils::repair_part(), activity_handlers::robot_control_finish(), talk_trial::roll(), smash(), activity_handlers::start_fire_finish(), activity_handlers::study_spell_finish(), avatar_action::swim(), ranged::throw_item(), place_trap_actor::use(), and sew_advanced_actor::use().

◆ print_health()

void Character::print_health ( ) const

Definition at line 4183 of file character.cpp.

4184{
4185 if( !is_player() ) {
4186 return;
4187 }
4188 int current_health = get_healthy();
4189 if( has_trait( trait_SELFAWARE ) ) {
4190 add_msg_if_player( _( "Your current health value is %d." ), current_health );
4191 }
4192
4193 static const std::map<int, std::string> msg_categories = {
4194 { -100, "health_horrible" },
4195 { -50, "health_very_bad" },
4196 { -10, "health_bad" },
4197 { 10, "" },
4198 { 50, "health_good" },
4199 { 100, "health_very_good" },
4200 { INT_MAX, "health_great" }
4201 };
4202
4203 auto iter = msg_categories.lower_bound( current_health );
4204 if( iter != msg_categories.end() && !iter->second.empty() ) {
4205 const translation msg = SNIPPET.random_from_category( iter->second ).value_or( translation() );
4206 add_msg_if_player( current_health > 0 ? m_good : m_bad, "%s", msg );
4207 }
4208}

References _, Creature::add_msg_if_player(), get_healthy(), has_trait(), Creature::is_player(), m_bad, m_good, snippet_library::random_from_category(), SNIPPET, and trait_SELFAWARE.

Referenced by activate_mutation(), and avatar::wake_up().

◆ print_info()

int Character::print_info ( const catacurses::window w,
int  vStart,
int  vLines,
int  column 
) const
overridevirtual

Write information about this creature.

Parameters
wthe window to print the text into.
vStartvertical start to print, that means the first line to print.
vLinesnumber of lines to print at most (printing less is fine).
columnhorizontal start to print (column), horizontal end is one character before the right border of the window (to keep the border).
Returns
The line just behind the last printed line, that means multiple calls to this can be stacked, the return value is acceptable as vStart for the next call without creating empty lines or overwriting lines.

Implements Creature.

Reimplemented in npc.

Definition at line 10308 of file character.cpp.

10309{
10310 mvwprintw( w, point( column, vStart++ ), _( "You (%s)" ), name );
10311 return vStart;
10312}
void mvwprintw(const window &win, const point &p, const std::string &text)

References _, catacurses::mvwprintw(), and name.

◆ process_bionic()

void Character::process_bionic ( bionic bio)

Handles bionic effects over time of the entered bionic.

Definition at line 1523 of file bionics.cpp.

1524{
1525 if( ( !bio.id->fuel_opts.empty() || bio.id->is_remote_fueled ) && bio.is_auto_start_on() ) {
1526 const float start_threshold = bio.get_auto_start_thresh();
1527 std::vector<itype_id> fuel_available = get_fuel_available( bio.id );
1528 if( bio.id->is_remote_fueled ) {
1529 const itype_id rem_fuel = find_remote_fuel();
1530 const std::string rem_amount = get_value( "rem_" + rem_fuel.str() );
1531 int rem_fuel_stock = 0;
1532 if( !rem_amount.empty() ) {
1533 rem_fuel_stock = std::stoi( rem_amount );
1534 }
1535 if( !rem_fuel.is_empty() && ( rem_fuel_stock > 0 ||
1536 item( rem_fuel ).has_flag( flag_PERPETUAL ) ) ) {
1537 fuel_available.emplace_back( rem_fuel );
1538 }
1539 }
1540 if( !fuel_available.empty() && get_power_level() <= start_threshold * get_max_power_level() ) {
1541 g->u.activate_bionic( bio );
1542 } else if( get_power_level() <= start_threshold * get_max_power_level() &&
1543 calendar::once_every( 1_hours ) ) {
1544 add_msg_player_or_npc( m_bad, _( "Your %s does not have enough fuel to use Auto Start." ),
1545 _( "<npcname>'s %s does not have enough fuel to use Auto Start." ),
1546 bio.info().name );
1547 }
1548 }
1549
1550 // Only powered bionics should be processed
1551 if( !bio.powered ) {
1552 passive_power_gen( bio );
1553 return;
1554 }
1555
1556 // These might be affected by environmental conditions, status effects, faulty bionics, etc.
1557 int discharge_factor = 1;
1558 int discharge_rate = 1;
1559
1560 if( bio.charge_timer > 0 ) {
1561 bio.charge_timer -= discharge_rate;
1562 } else {
1563 if( bio.info().charge_time > 0 ) {
1564 if( bio.info().has_flag( STATIC( flag_str_id( "BIONIC_POWER_SOURCE" ) ) ) ) {
1565 // Convert fuel to bionic power
1566 burn_fuel( bio );
1567 // This is our first turn of charging, so subtract a turn from the recharge delay.
1568 bio.charge_timer = std::max( 0, bio.info().charge_time - 1 );
1569 } else {
1570 // Try to recharge our bionic if it is made for it
1571 units::energy cost = 0_J;
1572 bool recharged = attempt_recharge( *this, bio, cost, discharge_factor, discharge_rate );
1573 if( !recharged ) {
1574 // No power to recharge, so deactivate
1575 bio.powered = false;
1576 add_msg_if_player( m_neutral, _( "Your %s powers down." ), bio.info().name );
1577 // This purposely bypasses the deactivation cost
1578 deactivate_bionic( bio, true );
1579 return;
1580 }
1581 if( cost > 0_J ) {
1582 mod_power_level( -cost );
1583 }
1584 }
1585 }
1586 }
1587
1588 // Bionic effects on every turn they are active go here.
1589 if( bio.id == bio_remote ) {
1590 if( g->remoteveh() == nullptr && get_value( "remote_controlling" ).empty() ) {
1591 bio.powered = false;
1592 add_msg_if_player( m_warning, _( "Your %s has lost connection and is turning off." ),
1593 bio.info().name );
1594 }
1595 } else if( bio.id == bio_hydraulics ) {
1596 // Sound of hissing hydraulic muscle! (not quite as loud as a car horn)
1597 sounds::sound( pos(), 19, sounds::sound_t::activity, _( "HISISSS!" ), false, "bionic",
1598 static_cast<std::string>( bio_hydraulics ) );
1599 } else if( bio.id == bio_nanobots ) {
1600 // Total hack, prevents charge_timer reaching 0 thus preventing power draw.
1601 // Ideally there would be a value that directly impacts whether a bionic draws power when idle.
1602 bio.charge_timer = 2;
1603 // The above hack means there's no check for whether the bionic actually has power to run.
1604 if( get_power_level() < bio.info().power_over_time ) {
1605 bio.powered = false;
1606 add_msg_if_player( m_warning, _( "Your %s shut down due to lack of power." ), bio.info().name );
1607 deactivate_bionic( bio );
1608 return;
1609 } else if( get_stored_kcal() < 0.85f * max_stored_kcal() ) {
1610 bio.powered = false;
1611 add_msg_if_player( m_warning, _( "Your %s shut down to conserve calories." ), bio.info().name );
1612 deactivate_bionic( bio );
1613 return;
1614 }
1615 if( calendar::once_every( 15_turns ) ) {
1616 std::vector<bodypart_id> bleeding_bp_parts;
1617 for( const bodypart_id &bp : get_all_body_parts() ) {
1618 if( has_effect( effect_bleed, bp.id() ) ) {
1619 bleeding_bp_parts.push_back( bp );
1620 }
1621 }
1622 if( !bleeding_bp_parts.empty() ) {
1623 const bodypart_id part_to_staunch = bleeding_bp_parts[ rng( 0, bleeding_bp_parts.size() - 1 ) ];
1624 effect &e = get_effect( effect_bleed, part_to_staunch->token );
1625 if( e.get_intensity() > 1 ) {
1626 e.mod_intensity( -1, false );
1627 } else {
1628 remove_effect( effect_bleed, part_to_staunch->token );
1629 }
1630 }
1631 if( rng( 0, 2 ) == 2 ) {
1632 std::vector<bodypart_id> damaged_hp_parts;
1633 for( const std::pair<const bodypart_str_id, bodypart> &part : get_body() ) {
1634 const int hp_cur = part.second.get_hp_cur();
1635 if( hp_cur > 0 && hp_cur < part.second.get_hp_max() ) {
1636 damaged_hp_parts.push_back( part.first.id() );
1637 }
1638 }
1639 if( get_stored_kcal() >= 5 && !damaged_hp_parts.empty() ) {
1640 const bodypart_id part_to_heal = damaged_hp_parts[ rng( 0, damaged_hp_parts.size() - 1 ) ];
1641 heal( part_to_heal, 1 );
1643 mod_stored_kcal( -5 );
1644 }
1645 }
1646 }
1647 } else if( bio.id == bio_painkiller ) {
1648 const int pkill = get_painkiller();
1649 const int pain = get_pain();
1650 const units::energy trigger_cost = bio.info().power_trigger;
1651 int max_pkill = std::min( 150, pain );
1652 if( pkill < max_pkill ) {
1653 mod_painkiller( 1 );
1654 mod_power_level( -trigger_cost );
1655 }
1656
1657 // Only dull pain so extreme that we can't pkill it safely
1658 if( pkill >= 150 && pain > pkill && get_stim() > -150 ) {
1659 mod_pain( -1 );
1660 // Negative side effect: negative stim
1661 mod_stim( -1 );
1662 mod_power_level( -trigger_cost );
1663 }
1664 } else if( bio.id == bio_gills ) {
1665 if( has_effect( effect_asthma ) ) {
1667 _( "You feel your throat open up and air filling your lungs!" ) );
1669 }
1670 } else if( bio.id == bio_evap ) {
1671 // Aero-Evaporator provides water at 60 watts with 2 L / kWh efficiency
1672 // which is 10 mL per 5 minutes. Humidity can modify the amount gained.
1673 if( calendar::once_every( 5_minutes ) ) {
1674 const w_point &weatherPoint = get_weather().get_precise();
1675 int humidity = get_local_humidity( weatherPoint.humidity, get_weather().weather_id,
1676 g->is_sheltered( g->u.pos() ) );
1677 // in thirst units = 5 mL water
1678 int water_available = std::lround( humidity * 3.0 / 100.0 );
1679 // At 50% relative humidity or more, the player will draw 10 mL
1680 // At 16% relative humidity or less, the bionic will give up
1681 if( water_available == 0 ) {
1683 _( "There is not enough humidity in the air for your %s to function." ),
1684 bio.info().name );
1685 deactivate_bionic( bio );
1686 } else if( water_available == 1 ) {
1688 _( "Your %s issues a low humidity warning. Efficiency is reduced." ),
1689 bio.info().name );
1690 }
1691
1692 mod_thirst( -water_available );
1693 }
1694
1697 _( "You are properly hydrated. Your %s chirps happily." ),
1698 bio.info().name );
1699 deactivate_bionic( bio );
1700 }
1701 } else if( bio.id == bio_ads ) {
1702 if( bio.charge_timer < 2 ) {
1703 bio.charge_timer = 2;
1704 }
1705 if( bio.energy_stored < 150_kJ ) {
1706 // Max recharge rate is influenced by whether you've been hit or not.
1707 // See character.cpp for how charge_timer keeps track of that for this bionic.
1708 units::energy max_rate = 10_kJ;
1709 if( bio.charge_timer > 2 ) {
1710 max_rate /= 2;
1711 }
1712 units::energy ads_recharge = std::min( max_rate, 150_kJ - bio.energy_stored );
1713 if( ads_recharge < get_power_level() ) {
1714 mod_power_level( - ads_recharge );
1715 bio.energy_stored += ads_recharge;
1716 } else if( get_power_level() != 0_kJ ) {
1719 }
1720 if( bio.energy_stored == 150_kJ ) {
1721 add_msg_if_player( m_good, _( "Your %s quietens to a satisfied thrum." ), bio.info().name );
1722 }
1723 } else if( bio.energy_stored > 150_kJ ) {
1724 bio.energy_stored = 150_kJ;
1725 }
1726 } else if( bio.id == afs_bio_dopamine_stimulators ) {
1727 add_morale( MORALE_FEELING_GOOD, 20, 20, 30_minutes, 20_minutes, true );
1728 }
1729}
static const efftype_id effect_bleed("bleed")
static bool attempt_recharge(Character &p, bionic &bio, units::energy &amount, int factor=1, int rate=1)
Definition: bionics.cpp:1503
static const efftype_id effect_asthma("asthma")
static const bionic_id afs_bio_dopamine_stimulators("afs_bio_dopamine_stimulators")
static const bionic_id bio_nanobots("bio_nanobots")
static const bionic_id bio_gills("bio_gills")
void mod_painkiller(int npkill)
Modifies intensity of painkillers
Definition: character.cpp:9739
void passive_power_gen(bionic &bio)
Passively produce power from PERPETUAL fuel.
Definition: bionics.cpp:1311
const morale_type MORALE_FEELING_GOOD("morale_feeling_good")
units::energy power_over_time
Power cost over time, does nothing without a non-zero charge_time.
Definition: bionics.h:41
float get_auto_start_thresh() const
Definition: bionics.cpp:2740
bool is_auto_start_on() const
Definition: bionics.cpp:2745

References _, sounds::activity, add_morale(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), afs_bio_dopamine_stimulators, attempt_recharge(), bio_ads, bio_evap, bio_gills, bio_hydraulics, bio_nanobots, bio_painkiller, bio_remote, burn_fuel(), bionic_data::charge_time, bionic::charge_timer, deactivate_bionic(), effect_asthma, effect_bleed, bionic::energy_stored, find_remote_fuel(), flag_PERPETUAL(), bionic_data::fuel_opts, g, Creature::get_all_body_parts(), bionic::get_auto_start_thresh(), Creature::get_body(), Creature::get_effect(), get_fuel_available(), effect::get_intensity(), get_local_humidity(), get_max_power_level(), Creature::get_pain(), get_painkiller(), get_power_level(), weather_manager::get_precise(), get_stim(), get_stored_kcal(), get_thirst(), Creature::get_value(), get_weather(), Creature::has_effect(), bionic_data::has_flag(), Creature::has_flag(), heal(), w_point::humidity, hydrated, bionic::id, string_id< T >::id(), bionic::info(), bionic::is_auto_start_on(), string_id< T >::is_empty(), bionic_data::is_remote_fueled, m_bad, m_good, m_mixed, m_neutral, m_warning, max_stored_kcal(), effect::mod_intensity(), mod_pain(), mod_painkiller(), mod_power_level(), mod_stim(), mod_stored_kcal(), mod_thirst(), MORALE_FEELING_GOOD, bionic_data::name, calendar::once_every(), Creature::pain, passive_power_gen(), pkill, pos(), bionic_data::power_over_time, bionic_data::power_trigger, bionic::powered, Creature::remove_effect(), rng(), sounds::sound(), STATIC, and string_id< T >::str().

Referenced by suffer().

◆ process_effects_internal()

void Character::process_effects_internal ( )
overridevirtual

Processes human-specific effects of effects before calling Creature::process_effects().

Implements Creature.

Definition at line 535 of file character_turn.cpp.

536{
537 //Special Removals
538 if( has_effect( effect_darkness ) && g->is_in_sunlight( pos() ) ) {
540 }
542 vomit();
544 add_msg_if_player( m_bad, _( "We have mistakenly colonized a local guide! Purging now." ) );
545 }
556 add_msg_if_player( m_good, _( "Something writhes and inside of you as it dies." ) );
557 }
564 }
567 add_msg_if_player( m_good, _( "Your bowels gurgle as something inside them dies." ) );
568 }
569
570 //Human only effects
571 for( auto &elem : *effects ) {
572 for( auto &_effect_it : elem.second ) {
573 if( !_effect_it.second.is_removed() ) {
574 process_one_effect( _effect_it.second, false );
575 }
576 }
577 }
578}
static const efftype_id effect_bloodworms("bloodworms")
static const efftype_id effect_fungus("fungus")
static const efftype_id effect_dermatik("dermatik")
static const trait_id trait_M_IMMUNE("M_IMMUNE")
static const efftype_id effect_tapeworm("tapeworm")
static const trait_id trait_PARAIMMUNE("PARAIMMUNE")
static const efftype_id effect_darkness("darkness")
static const efftype_id effect_paincysts("paincysts")
static const trait_id trait_EATHEALTH("EATHEALTH")
static const trait_id trait_ACIDBLOOD("ACIDBLOOD")
static const efftype_id effect_brainworms("brainworms")
void process_one_effect(effect &it, bool is_new) override
Processes human-specific effects of an effect.

References _, Creature::add_msg_if_player(), effect_bloodworms, effect_brainworms, effect_darkness, effect_dermatik, effect_fungus, effect_paincysts, effect_tapeworm, Creature::effects, g, Creature::has_effect(), has_trait(), m_bad, m_good, pos(), process_one_effect(), Creature::remove_effect(), trait_ACIDBLOOD, trait_EATHEALTH, trait_M_IMMUNE, trait_PARAIMMUNE, and vomit().

◆ process_items()

void Character::process_items ( )

Process active items.

Definition at line 806 of file character_turn.cpp.

807{
808 if( weapon.needs_processing() && weapon.process( as_player(), pos(), false ) ) {
809 weapon = item();
810 }
811
812 std::vector<item *> inv_active = inv.active_items();
813 for( item *tmp_it : inv_active ) {
814 if( tmp_it->process( as_player(), pos(), false ) ) {
815 inv.remove_item( tmp_it );
816 }
817 }
818
819 // worn items
820 remove_worn_items_with( [this]( item & itm ) {
821 return itm.needs_processing() && itm.process( as_player(), pos(), false );
822 } );
823
824 // Active item processing done, now we're recharging.
825 std::vector<item *> active_worn_items;
826 bool weapon_active = weapon.has_flag( "USE_UPS" ) &&
828 std::vector<size_t> active_held_items;
829 int ch_UPS = 0;
830 for( size_t index = 0; index < inv.size(); index++ ) {
831 item &it = inv.find_item( index );
832 itype_id identifier = it.type->get_id();
833 if( identifier == itype_UPS_off ) {
834 ch_UPS += it.ammo_remaining();
835 } else if( identifier == itype_adv_UPS_off ) {
836 ch_UPS += it.ammo_remaining() / 0.6;
837 }
838 if( it.has_flag( "USE_UPS" ) && it.charges < it.type->maximum_charges() ) {
839 active_held_items.push_back( index );
840 }
841 }
842 bool update_required = get_check_encumbrance();
843 for( item &w : worn ) {
844 if( w.has_flag( "USE_UPS" ) &&
845 w.charges < w.type->maximum_charges() ) {
846 active_worn_items.push_back( &w );
847 }
848 // Necessary for UPS in Aftershock - check worn items for charge
849 const itype_id &identifier = w.typeId();
850 if( identifier == itype_UPS_off ) {
851 ch_UPS += w.ammo_remaining();
852 } else if( identifier == itype_adv_UPS_off ) {
853 ch_UPS += w.ammo_remaining() / 0.6;
854 }
855 if( !update_required && w.encumbrance_update_ ) {
856 update_required = true;
857 }
858 w.encumbrance_update_ = false;
859 }
860 if( update_required ) {
862 }
863 if( has_active_bionic( bionic_id( "bio_ups" ) ) ) {
865 }
866 int ch_UPS_used = 0;
867
868 // Load all items that use the UPS to their minimal functional charge,
869 // The tool is not really useful if its charges are below charges_to_use
870 for( size_t index : active_held_items ) {
871 if( ch_UPS_used >= ch_UPS ) {
872 break;
873 }
874 item &it = inv.find_item( index );
875 ch_UPS_used++;
876 it.charges++;
877 }
878 if( weapon_active && ch_UPS_used < ch_UPS ) {
879 ch_UPS_used++;
880 weapon.charges++;
881 }
882 for( item *worn_item : active_worn_items ) {
883 if( ch_UPS_used >= ch_UPS ) {
884 break;
885 }
886 ch_UPS_used++;
887 worn_item->charges++;
888 }
889 if( ch_UPS_used > 0 ) {
890 use_charges( itype_UPS, ch_UPS_used );
891 }
892}
static const itype_id itype_adv_UPS_off("adv_UPS_off")
static const itype_id itype_UPS("UPS")
static const itype_id itype_UPS_off("UPS_off")
bool get_check_encumbrance()
Definition: character.h:1986
std::vector< item * > active_items()
Definition: inventory.cpp:1089
size_t size() const
Definition: inventory.cpp:167
bool process(player *carrier, const tripoint &pos, bool activate, temperature_flag flag=temperature_flag::TEMP_NORMAL)
This is called once each turn.
Definition: item.cpp:9591
bool needs_processing() const
Whether the item should be processed (by calling process).
Definition: item.cpp:8935
int maximum_charges() const
Definition: itype.h:1096

References inventory::active_items(), item::ammo_remaining(), Creature::as_player(), bionic_id, item::charges, inventory::find_item(), get_check_encumbrance(), itype::get_id(), get_power_level(), has_active_bionic(), item::has_flag(), inv, itype_adv_UPS_off, itype_UPS, itype_UPS_off, itype::maximum_charges(), item::needs_processing(), pos(), item::process(), inventory::remove_item(), remove_worn_items_with(), reset_encumbrance(), inventory::size(), units::to_kilojoule(), item::type, use_charges(), weapon, and worn.

Referenced by npc::on_load(), and process_turn().

◆ process_one_effect()

void Character::process_one_effect ( effect it,
bool  is_new 
)
overridevirtual

Processes human-specific effects of an effect.

Implements Creature.

Definition at line 326 of file character_turn.cpp.

327{
328 bool reduced = resists_effect( it );
329 double mod = 1;
330 body_part bp = it.get_bp()->token;
331 int val = 0;
332
333 // Still hardcoded stuff, do this first since some modify their other traits
334 hardcoded_effects( it );
335
336 const auto get_effect = [&it, is_new]( const std::string & arg, bool reduced ) {
337 if( is_new ) {
338 return it.get_amount( arg, reduced );
339 }
340 return it.get_mod( arg, reduced );
341 };
342
343 // Handle miss messages
344 auto msgs = it.get_miss_msgs();
345 if( !msgs.empty() ) {
346 for( const auto &i : msgs ) {
347 add_miss_reason( _( i.first ), static_cast<unsigned>( i.second ) );
348 }
349 }
350
351 // Handle health mod
352 val = get_effect( "H_MOD", reduced );
353 if( val != 0 ) {
354 mod = 1;
355 if( is_new || it.activated( calendar::turn, "H_MOD", val, reduced, mod ) ) {
356 int bounded = bound_mod_to_vals(
357 get_healthy_mod(), val, it.get_max_val( "H_MOD", reduced ),
358 it.get_min_val( "H_MOD", reduced ) );
359 // This already applies bounds, so we pass them through.
360 mod_healthy_mod( bounded, get_healthy_mod() + bounded );
361 }
362 }
363
364 // Handle health
365 val = get_effect( "HEALTH", reduced );
366 if( val != 0 ) {
367 mod = 1;
368 if( is_new || it.activated( calendar::turn, "HEALTH", val, reduced, mod ) ) {
370 it.get_max_val( "HEALTH", reduced ), it.get_min_val( "HEALTH", reduced ) ) );
371 }
372 }
373
374 // Handle stim
375 val = get_effect( "STIM", reduced );
376 if( val != 0 ) {
377 mod = 1;
378 if( is_new || it.activated( calendar::turn, "STIM", val, reduced, mod ) ) {
379 mod_stim( bound_mod_to_vals( get_stim(), val, it.get_max_val( "STIM", reduced ),
380 it.get_min_val( "STIM", reduced ) ) );
381 }
382 }
383
384 // Handle hunger
385 val = get_effect( "HUNGER", reduced );
386 if( val != 0 ) {
387 mod = 1;
388 if( is_new || it.activated( calendar::turn, "HUNGER", val, reduced, mod ) ) {
390 val, it.get_max_val( "HUNGER", reduced ), it.get_min_val( "HUNGER", reduced ) ) );
391 }
392 }
393
394 // Handle thirst
395 val = get_effect( "THIRST", reduced );
396 if( val != 0 ) {
397 mod = 1;
398 if( is_new || it.activated( calendar::turn, "THIRST", val, reduced, mod ) ) {
399 mod_thirst( bound_mod_to_vals( get_thirst(), val, it.get_max_val( "THIRST", reduced ),
400 it.get_min_val( "THIRST", reduced ) ) );
401 }
402 }
403
404 // Handle fatigue
405 val = get_effect( "FATIGUE", reduced );
406 // Prevent ongoing fatigue effects while asleep.
407 // These are meant to change how fast you get tired, not how long you sleep.
408 if( val != 0 && !in_sleep_state() ) {
409 mod = 1;
410 if( is_new || it.activated( calendar::turn, "FATIGUE", val, reduced, mod ) ) {
411 mod_fatigue( bound_mod_to_vals( get_fatigue(), val, it.get_max_val( "FATIGUE", reduced ),
412 it.get_min_val( "FATIGUE", reduced ) ) );
413 }
414 }
415
416 // Handle Radiation
417 val = get_effect( "RAD", reduced );
418 if( val != 0 ) {
419 mod = 1;
420 if( is_new || it.activated( calendar::turn, "RAD", val, reduced, mod ) ) {
421 mod_rad( bound_mod_to_vals( get_rad(), val, it.get_max_val( "RAD", reduced ), 0 ) );
422 // Radiation can't go negative
423 if( get_rad() < 0 ) {
424 set_rad( 0 );
425 }
426 }
427 }
428
429 // Handle Pain
430 val = get_effect( "PAIN", reduced );
431 if( val != 0 ) {
432 mod = 1;
433 if( it.get_sizing( "PAIN" ) ) {
434 if( has_trait( trait_FAT ) ) {
435 mod *= 1.5;
436 }
437 if( get_size() == MS_LARGE ) {
438 mod *= 2;
439 }
440 if( get_size() == MS_HUGE ) {
441 mod *= 3;
442 }
443 }
444 if( is_new || it.activated( calendar::turn, "PAIN", val, reduced, mod ) ) {
445 int pain_inc = bound_mod_to_vals( get_pain(), val, it.get_max_val( "PAIN", reduced ), 0 );
446 mod_pain( pain_inc );
447 if( pain_inc > 0 ) {
448 character_funcs::add_pain_msg( *this, val, bp );
449 }
450 }
451 }
452
453 // Handle Damage
454 val = get_effect( "HURT", reduced );
455 if( val != 0 ) {
456 mod = 1;
457 if( it.get_sizing( "HURT" ) ) {
458 if( has_trait( trait_FAT ) ) {
459 mod *= 1.5;
460 }
461 if( get_size() == MS_LARGE ) {
462 mod *= 2;
463 }
464 if( get_size() == MS_HUGE ) {
465 mod *= 3;
466 }
467 }
468 if( is_new || it.activated( calendar::turn, "HURT", val, reduced, mod ) ) {
469 if( bp == num_bp ) {
470 if( val > 5 ) {
471 add_msg_if_player( _( "Your %s HURTS!" ), body_part_name_accusative( bp_torso ) );
472 } else {
473 add_msg_if_player( _( "Your %s hurts!" ), body_part_name_accusative( bp_torso ) );
474 }
475 apply_damage( nullptr, bodypart_id( "torso" ), val, true );
476 } else {
477 if( val > 5 ) {
478 add_msg_if_player( _( "Your %s HURTS!" ), body_part_name_accusative( bp ) );
479 } else {
480 add_msg_if_player( _( "Your %s hurts!" ), body_part_name_accusative( bp ) );
481 }
482 apply_damage( nullptr, convert_bp( bp ).id(), val, true );
483 }
484 }
485 }
486
487 // Handle Sleep
488 val = get_effect( "SLEEP", reduced );
489 if( val != 0 ) {
490 mod = 1;
491 if( ( is_new || it.activated( calendar::turn, "SLEEP", val, reduced, mod ) ) &&
492 !has_effect( efftype_id( "sleep" ) ) ) {
493 add_msg_if_player( _( "You pass out!" ) );
495 }
496 }
497
498 // Handle painkillers
499 val = get_effect( "PKILL", reduced );
500 if( val != 0 ) {
502 if( is_new || it.activated( calendar::turn, "PKILL", val, reduced, mod ) ) {
503 mod_painkiller( bound_mod_to_vals( get_painkiller(), val, it.get_max_val( "PKILL", reduced ), 0 ) );
504 }
505 }
506
507 // Handle coughing
508 mod = 1;
509 val = 0;
510 if( it.activated( calendar::turn, "COUGH", val, reduced, mod ) ) {
511 cough( it.get_harmful_cough() );
512 }
513
514 // Handle vomiting
516 val = 0;
517 if( it.activated( calendar::turn, "VOMIT", val, reduced, mod ) ) {
518 vomit();
519 }
520
521 // Handle stamina
522 val = get_effect( "STAMINA", reduced );
523 if( val != 0 ) {
524 mod = 1;
525 if( is_new || it.activated( calendar::turn, "STAMINA", val, reduced, mod ) ) {
527 it.get_max_val( "STAMINA", reduced ),
528 it.get_min_val( "STAMINA", reduced ) ) );
529 }
530 }
531
532 // Speed and stats are handled in recalc_speed_bonus and reset_stats respectively
533}
int bound_mod_to_vals(int val, int mod, int max, int min)
Clamp the value of a modifier in order to bound the resulting value.
static const trait_id trait_FAT("FAT")
virtual int get_healthy_mod() const
Definition: character.cpp:4133
void cough(bool harmful=false, int loudness=4)
Definition: character.cpp:7507
void hardcoded_effects(effect &it)
Handles the still hard-coded effects.
bool resists_effect(const effect &e) const
Returns true if the creature resists an effect.
Definition: creature.cpp:1316
bool get_sizing(const std::string &arg) const
Returns true if the given modifier type's trigger chance is affected by size mutations.
Definition: effect.cpp:1021
bool get_harmful_cough() const
Returns true if the coughs caused by an effect can harm the player directly.
Definition: effect.cpp:1199
int get_mod(std::string arg, bool reduced=false) const
Returns the matching modifier type from an effect, used for getting actual effect effects.
Definition: effect.cpp:910
int get_max_val(std::string arg, bool reduced=false) const
Returns the maximum value of a modifier type that get_mod() and get_amount() will push the player to.
Definition: effect.cpp:1006
double get_addict_mod(const std::string &arg, int addict_level) const
Returns the modifier caused by addictions.
Definition: effect.cpp:1185
std::vector< std::pair< std::string, int > > get_miss_msgs() const
Returns a vector of the miss message messages and chances for use in add_miss_reason() while the effe...
Definition: effect.cpp:1216
bool activated(const time_point &when, std::string arg, int val, bool reduced=false, double mod=1) const
Checks to see if a given modifier type can activate, and performs any rolls required to do so.
Definition: effect.cpp:1108
int get_min_val(std::string arg, bool reduced=false) const
Returns the minimum value of a modifier type that get_mod() and get_amount() will push the player to.
Definition: effect.cpp:991
void add_pain_msg(const Character &who, int val, body_part bp)
Add message describing how character feels pain.

References _, effect::activated(), add_miss_reason(), Creature::add_msg_if_player(), character_funcs::add_pain_msg(), addiction_level(), apply_damage(), arg(), body_part_name_accusative(), bound_mod_to_vals(), bp_torso, convert_bp(), cough(), efftype_id, fall_asleep(), time_duration::from_turns(), effect::get_addict_mod(), effect::get_amount(), effect::get_bp(), Creature::get_effect(), get_fatigue(), effect::get_harmful_cough(), get_healthy(), get_healthy_mod(), effect::get_max_val(), effect::get_min_val(), effect::get_miss_msgs(), effect::get_mod(), Creature::get_pain(), get_painkiller(), get_rad(), get_size(), effect::get_sizing(), get_stamina(), get_stim(), get_stored_kcal(), get_thirst(), hardcoded_effects(), Creature::has_effect(), has_trait(), in_sleep_state(), max_stored_kcal(), mod_fatigue(), mod_healthy(), mod_healthy_mod(), mod_pain(), mod_painkiller(), mod_rad(), mod_stamina(), mod_stim(), mod_stored_kcal(), mod_thirst(), MS_HUGE, MS_LARGE, num_bp, PKILLER, Creature::resists_effect(), set_rad(), body_part_type::token, trait_FAT, calendar::turn, vomit(), and character_effects::vomit_mod().

Referenced by process_effects_internal().

◆ process_turn()

void Character::process_turn ( )
overridevirtual

Handles end-of-turn processing.

Reimplemented from Creature.

Reimplemented in npc.

Definition at line 165 of file character_turn.cpp.

166{
167 // Has to happen before reset_stats
169
170 for( bionic &i : *my_bionics ) {
171 if( i.incapacitated_time > 0_turns ) {
172 i.incapacitated_time -= 1_turns;
173 if( i.incapacitated_time == 0_turns ) {
174 add_msg_if_player( m_bad, _( "Your %s bionic comes back online." ), i.info().name );
175 }
176 }
177 }
178
180
181 // If we're actively handling something we can't just drop it on the ground
182 // in the middle of handling it
183 if( activity.targets.empty() ) {
185 }
187 // Didn't just pick something up
188 last_item = itype_id( "null" );
189
192 }
193
194 visit_items( [this]( item * e ) {
195 e->process_artifact( as_player(), pos() );
196 e->process_relic( *this );
197 return VisitResponse::NEXT;
198 } );
199
200 suffer();
201 // NPCs currently don't make any use of their scent, pointless to calculate it
202 // TODO: make use of NPC scent.
203 if( !is_npc() ) {
206 }
207 const int mask_intensity = get_effect_int( effect_masked_scent );
208
209 // Set our scent towards the norm
210 int norm_scent = 500;
211 int temp_norm_scent = INT_MIN;
212 bool found_intensity = false;
213 for( const trait_id &mut : get_mutations() ) {
214 const cata::optional<int> &scent_intensity = mut->scent_intensity;
215 if( scent_intensity ) {
216 found_intensity = true;
217 temp_norm_scent = std::max( temp_norm_scent, *scent_intensity );
218 }
219 }
220 if( found_intensity ) {
221 norm_scent = temp_norm_scent;
222 }
223
224 for( const trait_id &mut : get_mutations() ) {
225 const cata::optional<int> &scent_mask = mut->scent_mask;
226 if( scent_mask ) {
227 norm_scent += *scent_mask;
228 }
229 }
230
231 //mask from scent altering items;
232 norm_scent += mask_intensity;
233
234 // Scent increases fast at first, and slows down as it approaches normal levels.
235 // Estimate it will take about norm_scent * 2 turns to go from 0 - norm_scent / 2
236 // Without smelly trait this is about 1.5 hrs. Slows down significantly after that.
237 if( scent < rng( 0, norm_scent ) ) {
238 scent++;
239 }
240
241 // Unusually high scent decreases steadily until it reaches normal levels.
242 if( scent > norm_scent ) {
243 scent--;
244 }
245
246 for( const trait_id &mut : get_mutations() ) {
247 scent *= mut.obj().scent_modifier;
248 }
249 }
250
251 // We can dodge again! Assuming we can actually move...
252 if( in_sleep_state() ) {
253 blocks_left = 0;
254 dodges_left = 0;
255 } else if( moves > 0 ) {
258 }
259
260 // auto-learning. This is here because skill-increases happens all over the place:
261 // SkillLevel::readBook (has no connection to the skill or the player),
262 // player::read, player::practice, ...
263 // Check for spontaneous discovery of martial art styles
264 for( auto &style : autolearn_martialart_types() ) {
265 const matype_id &ma( style );
266
267 if( !martial_arts_data->has_martialart( ma ) && can_autolearn_martial_art( *this, ma ) ) {
268 martial_arts_data->add_martialart( ma );
269 add_msg_if_player( m_info, _( "You have learned a new style: %s!" ), ma.obj().name );
270 }
271 }
272
273 // Update time spent conscious in this overmap tile for the Nomad traits.
274 if( !is_npc() && ( has_trait( trait_NOMAD ) || has_trait( trait_NOMAD2 ) ||
275 has_trait( trait_NOMAD3 ) ) &&
278 const point_abs_omt pos = ompos.xy();
279 if( overmap_time.find( pos ) == overmap_time.end() ) {
280 overmap_time[pos] = 1_turns;
281 } else {
282 overmap_time[pos] += 1_turns;
283 }
284 }
285 // Decay time spent in other overmap tiles.
286 if( !is_npc() && calendar::once_every( 1_hours ) ) {
288 const time_point now = calendar::turn;
289 time_duration decay_time = 0_days;
290 if( has_trait( trait_NOMAD ) ) {
291 decay_time = 7_days;
292 } else if( has_trait( trait_NOMAD2 ) ) {
293 decay_time = 14_days;
294 } else if( has_trait( trait_NOMAD3 ) ) {
295 decay_time = 28_days;
296 }
297 auto it = overmap_time.begin();
298 while( it != overmap_time.end() ) {
299 if( it->first == ompos.xy() ) {
300 it++;
301 continue;
302 }
303 // Find the amount of time passed since the player touched any of the overmap tile's submaps.
304 const tripoint_abs_omt tpt( it->first, 0 );
305 const time_point last_touched = overmap_buffer.scent_at( tpt ).creation_time;
306 const time_duration since_visit = now - last_touched;
307 // If the player has spent little time in this overmap tile, let it decay after just an hour instead of the usual extended decay time.
308 const time_duration modified_decay_time = it->second > 5_minutes ? decay_time : 1_hours;
309 if( since_visit > modified_decay_time ) {
310 // Reduce the tracked time spent in this overmap tile.
311 const time_duration decay_amount = std::min( since_visit - modified_decay_time, 1_hours );
312 const time_duration updated_value = it->second - decay_amount;
313 if( updated_value <= 0_turns ) {
314 // We can stop tracking this tile if there's no longer any time recorded there.
315 it = overmap_time.erase( it );
316 continue;
317 } else {
318 it->second = updated_value;
319 }
320 }
321 it++;
322 }
323 }
324}
static const efftype_id effect_narcosis("narcosis")
static const efftype_id effect_masked_scent("masked_scent")
static const trait_id trait_NOMAD2("NOMAD2")
static const trait_id trait_NOMAD3("NOMAD3")
static const trait_id trait_NOMAD("NOMAD")
static const efftype_id effect_sleep("sleep")
static const trait_id trait_DEBUG_BIONIC_POWER("DEBUG_BIONIC_POWER")
void process_items()
Process active items.
void clear_miss_reasons()
Clears the list of reasons for why the player would miss a melee attack.
Definition: melee.cpp:327
void suffer()
Handles a large number of timers decrementing and other randomized effects.
Definition: suffer.cpp:1472
virtual void process_turn()
Processes effects and bonuses and allocates move points based on speed.
Definition: creature.cpp:152
virtual int get_num_dodges() const
Definition: creature.cpp:1450
virtual int get_num_blocks() const
Definition: creature.cpp:1446
void process_artifact(player *carrier, const tripoint &pos)
Process and apply artifact effects.
Definition: item.cpp:9061
void process_relic(Character &carrier)
Definition: item.cpp:9103
scent_trace scent_at(const tripoint_abs_omt &pos)
Method to retrieve the scent at a given location.
std::vector< item_location > targets
time_point creation_time
Definition: overmap_types.h:15
A point in the game time.
Definition: calendar.h:431
std::vector< matype_id > autolearn_martialart_types()
bool can_autolearn_martial_art(const Character &who, const matype_id &ma_id)
Returns true if the character can learn the entered martial art.

References _, activity, Creature::add_msg_if_player(), Creature::as_player(), autolearn_martialart_types(), blocks_left, can_autolearn_martial_art(), clear_miss_reasons(), scent_trace::creation_time, dodges_left, drop_invalid_inventory(), effect_masked_scent, effect_narcosis, effect_sleep, Creature::get_effect_int(), get_max_power_level(), get_mutations(), Creature::get_num_blocks(), Creature::get_num_dodges(), global_omt_location(), Creature::has_effect(), has_trait(), in_sleep_state(), Creature::is_npc(), itype_id, last_item, m_bad, m_info, martial_arts_data, mod_power_level(), Creature::moves, my_bionics, martialart::name, NEXT, string_id< T >::obj(), calendar::once_every(), overmap_buffer, overmap_time, pos(), item::process_artifact(), process_items(), item::process_relic(), Creature::process_turn(), restore_scent(), rng(), scent, overmapbuffer::scent_at(), suffer(), player_activity::targets, trait_DEBUG_BIONIC_POWER, trait_NOMAD, trait_NOMAD2, trait_NOMAD3, calendar::turn, visitable< Character >::visit_items(), and coords::coord_point< Point, Origin, Scale >::xy().

Referenced by game::do_turn(), npc::process_turn(), and game::start_game().

◆ query_yn() [1/2]

template<typename ... Args>
bool Character::query_yn ( const char *const  msg,
Args &&...  args 
) const
inline

It is supposed to hide the query_yn to simplify player vs.

npc code.

Definition at line 1460 of file character.h.

1460 {
1461 return query_yn( string_format( msg, std::forward<Args>( args ) ... ) );
1462 }

References query_yn(), and string_format().

Referenced by activate_bionic(), can_install_bionics(), feed_reactor_with(), query_yn(), takeoff(), and will_eat().

◆ query_yn() [2/2]

virtual bool Character::query_yn ( const std::string &  msg) const
pure virtual

Implemented in npc, player, and player.

◆ ranged_dex_mod()

int Character::ranged_dex_mod ( ) const
virtual
Dexterity <20 increases ranged penalty

Definition at line 4117 of file character.cpp.

4118{
4119 ///\EFFECT_DEX <20 increases ranged penalty
4120 return std::max( ( 20.0 - get_dex() ) * 0.5, 0.0 );
4121}

References get_dex().

Referenced by draw_stats_info(), ranged::get_weapon_dispersion(), and set_stats().

◆ ranged_per_mod()

int Character::ranged_per_mod ( ) const
virtual
Perception <20 increases ranged aiming penalty.

Definition at line 4123 of file character.cpp.

4124{
4125 ///\EFFECT_PER <20 increases ranged aiming penalty.
4126 return std::max( ( 20.0 - get_per() ) * 1.2, 0.0 );
4127}

References get_per().

Referenced by draw_stats_info(), ranged::effective_dispersion(), and set_stats().

◆ reach_attack()

void Character::reach_attack ( const tripoint p)

Handles reach melee attack on point p.

Melee >5 allows WHIP_DISARM technique Stabbing decreases chance of hitting intervening target on reach attack Stabbing increases ability to reach attack through fences Strength increases bash effects when reach attacking past something

Definition at line 620 of file melee.cpp.

621{
622 matec_id force_technique = tec_none;
623 /** @EFFECT_MELEE >5 allows WHIP_DISARM technique */
624 if( weapon.has_flag( "WHIP" ) && ( get_skill_level( skill_melee ) > 5 ) && one_in( 3 ) ) {
625 force_technique = matec_id( "WHIP_DISARM" );
626 }
627
628 map &here = get_map();
629 Creature *critter = g->critter_at( p );
630 // Original target size, used when there are monsters in front of our target
631 int target_size = critter != nullptr ? ( critter->get_size() + 1 ) : 2;
632 // Reset last target pos
634 // Max out recoil
636
638 int skill = std::min( 10, get_skill_level( skill_stabbing ) );
639 int t = 0;
640 std::vector<tripoint> path = line_to( pos(), p, t, 0 );
641 tripoint last_point = pos();
642 path.pop_back(); // Last point is our critter
643 for( const tripoint &path_point : path ) {
644 // Possibly hit some unintended target instead
645 Creature *inter = g->critter_at( path_point );
646 int inter_block_size = inter != nullptr ? ( inter->get_size() + 1 ) : 2;
647 /** @EFFECT_STABBING decreases chance of hitting intervening target on reach attack */
648 if( inter != nullptr &&
649 !x_in_y( ( target_size * target_size + 1 ) * skill,
650 ( inter_block_size * inter_block_size + 1 ) * 10 ) ) {
651 // Even if we miss here, low roll means weapon is pushed away or something like that
652 critter = inter;
653 break;
654 } else if( here.obstructed_by_vehicle_rotation( last_point, path_point ) ) {
655 tripoint rand = path_point;
656 if( one_in( 2 ) ) {
657 rand.x = last_point.x;
658 } else {
659 rand.y = last_point.y;
660 }
661
662 here.bash( rand, str_cur + weapon.damage_melee( DT_BASH ) );
665 return;
666 /** @EFFECT_STABBING increases ability to reach attack through fences */
667 } else if( here.impassable( path_point ) &&
668 // Fences etc. Spears can stab through those
669 !( weapon.has_flag( "SPEAR" ) &&
670 g->m.has_flag( "THIN_OBSTACLE", path_point ) &&
671 x_in_y( skill, 10 ) ) ) {
672 /** @EFFECT_STR increases bash effects when reach attacking past something */
673 here.bash( path_point, str_cur + weapon.damage_melee( DT_BASH ) );
676 return;
677 }
678 last_point = path_point;
679 }
680
681 if( here.obstructed_by_vehicle_rotation( last_point, p ) ) {
682 tripoint rand = p;
683 if( one_in( 2 ) ) {
684 rand.x = last_point.x;
685 } else {
686 rand.y = last_point.y;
687 }
688
689 here.bash( rand, str_cur + weapon.damage_melee( DT_BASH ) );
692 return;
693 }
694
695 if( critter == nullptr ) {
696 add_msg_if_player( _( "You swing at the air." ) );
697 if( martial_arts_data->has_miss_recovery_tec( weapon ) ) {
698 move_cost /= 3; // "Probing" is faster than a regular miss
699 }
700
702 return;
703 }
704
705 reach_attacking = true;
706 melee_attack( *critter, false, &force_technique, false );
707 reach_attacking = false;
708}
cata::optional< tripoint > last_target_pos
Definition: character.h:1564
virtual m_size get_size() const =0
bool obstructed_by_vehicle_rotation(const tripoint &from, const tripoint &to) const
Checks if a rotated vehicle is blocking diagonal movement, tripoints must be adjacent.
Definition: map.cpp:6498
bool impassable(const tripoint &p) const
Definition: map.cpp:1795
static const skill_id skill_stabbing("stabbing")
string_id< ma_technique > matec_id
Definition: type_id.h:89

References _, Creature::add_msg_if_player(), attack_cost(), map::bash(), item::damage_melee(), DT_BASH, g, get_map(), Creature::get_size(), get_skill_level(), handle_melee_wear(), item::has_flag(), map::impassable(), last_target_pos, line_to(), martial_arts_data, MAX_RECOIL, melee_attack(), Creature::mod_moves(), move_cost(), cata::nullopt, map::obstructed_by_vehicle_rotation(), one_in(), pos(), reach_attacking, recoil, skill_melee, skill_stabbing, str_cur, tec_none, weapon, tripoint::x, x_in_y(), and tripoint::y.

Referenced by npc::execute_action(), and reach_attack().

◆ react_to_felt_pain()

void Character::react_to_felt_pain ( int  intensity)

Definition at line 726 of file character.cpp.

727{
728 if( intensity <= 0 ) {
729 return;
730 }
731 if( is_player() && intensity >= 2 ) {
732 g->cancel_activity_or_ignore_query( distraction_type::pain, _( "Ouch, something hurts!" ) );
733 }
734 // Only a large pain burst will actually wake people while sleeping.
736 int pain_thresh = rng( 3, 5 );
737
739 pain_thresh += 2;
740 } else if( has_trait( trait_HEAVYSLEEPER2 ) ) {
741 pain_thresh += 5;
742 }
743
744 if( intensity >= pain_thresh ) {
745 wake_up();
746 }
747 }
748}
static const trait_id trait_HEAVYSLEEPER("HEAVYSLEEPER")
static const trait_id trait_HEAVYSLEEPER2("HEAVYSLEEPER2")

References _, effect_narcosis, effect_sleep, g, Creature::has_effect(), has_trait(), Creature::is_player(), pain, rng(), trait_HEAVYSLEEPER, trait_HEAVYSLEEPER2, and wake_up().

Referenced by set_pain(), and set_painkiller().

◆ read_speed()

int Character::read_speed ( bool  return_stat_effect = true) const

Returns the player's reading speed.

Intelligence increases reading speed by 3s per level above 8

Definition at line 3465 of file character.cpp.

3466{
3467 // Stat window shows stat effects on based on current stat
3468 const int intel = get_int();
3469 /** @EFFECT_INT increases reading speed by 3s per level above 8*/
3470 int ret = to_moves<int>( 1_minutes ) - to_moves<int>( 3_seconds ) * ( intel - 8 );
3471
3473 ret *= .75;
3474 }
3475
3476 ret *= mutation_value( "reading_speed_multiplier" );
3477
3478 if( ret < to_moves<int>( 1_seconds ) ) {
3479 ret = to_moves<int>( 1_seconds );
3480 }
3481 // return_stat_effect actually matters here
3482 return return_stat_effect ? ret : ret * 100 / to_moves<int>( 1_minutes );
3483}
static const bionic_id afs_bio_linguistic_coprocessor("afs_bio_linguistic_coprocessor")

References afs_bio_linguistic_coprocessor, get_int(), has_bionic(), mutation_value(), and cata::hash64_detail::ret.

Referenced by draw_stats_info(), read_inventory_preset::read_inventory_preset(), set_stats(), npc::time_to_read(), and avatar::time_to_read().

◆ rebuild_mutation_cache()

void Character::rebuild_mutation_cache ( )

Definition at line 7854 of file character.cpp.

7855{
7856 cached_mutations.clear();
7857 for( const std::pair<const trait_id, char_trait_data> &mut : my_mutations ) {
7858 cached_mutations.push_back( &mut.first.obj() );
7859 }
7860 for( const trait_id &mut : enchantment_cache->get_mutations() ) {
7861 cached_mutations.push_back( &mut.obj() );
7862 }
7863}

References cached_mutations, enchantment_cache, and my_mutations.

Referenced by set_mutation(), and unset_mutation().

◆ recalc_hp()

void Character::recalc_hp ( )

Recalculates HP after a change to max strength.

Definition at line 1563 of file character.cpp.

1564{
1565 int str_boost_val = 0;
1566 cata::optional<skill_boost> str_boost = skill_boost::get( "str" );
1567 if( str_boost ) {
1568 int skill_total = 0;
1569 for( const std::string &skill_str : str_boost->skills() ) {
1570 skill_total += get_skill_level( skill_id( skill_str ) );
1571 }
1572 str_boost_val = str_boost->calc_bonus( skill_total );
1573 }
1574 // Mutated toughness stacks with starting, by design.
1575 float hp_mod = 1.0f + mutation_value( "hp_modifier" ) + mutation_value( "hp_modifier_secondary" );
1576 float hp_adjustment = mutation_value( "hp_adjustment" ) + ( str_boost_val * 3 );
1577 calc_all_parts_hp( hp_mod, hp_adjustment, get_str_base() );
1578}
void calc_all_parts_hp(float hp_mod=0.0, float hp_adjust=0.0, int str_max=0)
Sets hp for all body parts.
Definition: character.cpp:1580
static cata::optional< skill_boost > get(const std::string &stat_str)
Definition: skill_boost.cpp:20

References calc_all_parts_hp(), skill_boost::get(), get_skill_level(), get_str_base(), mutation_value(), and skill_id.

Referenced by apply_mods(), apply_skill_boost(), avatar::create(), mutation_effect(), mutation_loss_effect(), character_funcs::normalize(), npc::randomize(), reset_scenario(), set_stats(), standard_npc::standard_npc(), and avatar::upgrade_stat().

◆ recalc_sight_limits()

void Character::recalc_sight_limits ( )

Modifies the player's sight values Must be called when any of the following change: This must be called when any of the following change:

  • effects
  • bionics
  • traits
  • underwater
  • clothes

Definition at line 1610 of file character.cpp.

1611{
1612 sight_max = 9999;
1613 vision_mode_cache.reset();
1614
1615 // Set sight_max.
1616 if( is_blind() || ( in_sleep_state() && !has_trait( trait_SEESLEEP ) ) ||
1618 sight_max = 0;
1619 } else if( has_effect( effect_boomered ) && ( !( has_trait( trait_PER_SLIME_OK ) ) ) ) {
1620 sight_max = 1;
1622 } else if( has_effect( effect_in_pit ) || has_effect( effect_no_sight ) ||
1626 sight_max = 1;
1627 } else if( has_active_mutation( trait_SHELL2 ) ) {
1628 // You can kinda see out a bit.
1629 sight_max = 2;
1630 } else if( ( has_trait( trait_MYOPIC ) || has_trait( trait_URSINE_EYE ) ) &&
1632 sight_max = 4;
1633 } else if( has_trait( trait_PER_SLIME ) ) {
1634 sight_max = 6;
1635 } else if( has_effect( effect_darkness ) ) {
1637 sight_max = 10;
1638 }
1639
1640 // Debug-only NV
1643 }
1644
1645 float best_bonus_nv = 0.0f;
1646 for( const mutation_branch *mut : cached_mutations ) {
1647 best_bonus_nv = std::max( best_bonus_nv, mut->night_vision_range );
1648 }
1650 ( is_mounted() && mounted_creature->has_flag( MF_MECH_RECON_VISION ) ) ) {
1651 best_bonus_nv = std::max( best_bonus_nv, 10.0f );
1652 }
1653 if( has_nv() ) {
1655 best_bonus_nv = std::max( best_bonus_nv, 10.0f );
1656 }
1657 if( has_trait( trait_BIRD_EYE ) ) {
1659 }
1660 if( has_trait( trait_URSINE_EYE ) ) {
1662 }
1663
1664 // +1 because of the ugly -1 in _from_per
1667 nv_range += best_bonus_nv;
1669 nv_range++;
1670 }
1671
1672 // Not exactly a sight limit thing, but related enough
1677 mounted_creature->has_flag( MF_MECH_RECON_VISION ) ) ) {
1679 }
1680
1682 has_effect_with_flag( "EFFECT_SUPER_CLAIRVOYANCE" ) ) {
1685 has_effect_with_flag( "EFFECT_CLAIRVOYANCE_PLUS" ) ) {
1687 } else if( has_artifact_with( AEP_CLAIRVOYANCE ) ||
1688 has_effect_with_flag( "EFFECT_CLAIRVOYANCE" ) ) {
1690 }
1691}
static const bionic_id bio_infrared("bio_infrared")
static const std::string flag_FIX_NEARSIGHT("FIX_NEARSIGHT")
static const efftype_id effect_contacts("contacts")
static const trait_id trait_CEPH_EYES("CEPH_EYES")
static const trait_id trait_INFRARED("INFRARED")
static const trait_id trait_LIZ_IR("LIZ_IR")
static const trait_id trait_URSINE_EYE("URSINE_EYE")
static const trait_id trait_MEMBRANE("MEMBRANE")
static const trait_id trait_MYOPIC("MYOPIC")
static const trait_id trait_BIRD_EYE("BIRD_EYE")
static const efftype_id effect_darkness("darkness")
static const bionic_id bio_membrane("bio_membrane")
static const std::string flag_SWIM_GOGGLES("SWIM_GOGGLES")
static const std::string flag_IR_EFFECT("IR_EFFECT")
static const trait_id trait_DEBUG_NIGHTVISION("DEBUG_NIGHTVISION")
static const trait_id trait_PER_SLIME_OK("PER_SLIME_OK")
static const efftype_id effect_no_sight("no_sight")
@ DARKNESS
Definition: character.h:92
@ URSINE_VISION
Definition: character.h:90
@ IR_VISION
Definition: character.h:93
@ BIRD_EYE
Definition: character.h:89
@ NV_GOGGLES
Definition: character.h:88
@ BOOMERED
Definition: character.h:91
bool has_nv()
Returns true if the player has some form of night vision.
Definition: character.cpp:3617
int sight_max
Definition: character.h:2151
@ AEP_CLAIRVOYANCE_PLUS
Definition: enums.h:142
@ AEP_SUPER_CLAIRVOYANCE
Definition: enums.h:112
@ AEP_CLAIRVOYANCE
Definition: enums.h:111
float nv_range_from_per(int per)
Definition: character.cpp:1703
float nv_range_from_eye_encumbrance(int enc)
Definition: character.cpp:1709

References AEP_CLAIRVOYANCE, AEP_CLAIRVOYANCE_PLUS, AEP_SUPER_CLAIRVOYANCE, bio_infrared, bio_membrane, BIRD_EYE, BOOMERED, bp_eyes, cached_mutations, DARKNESS, DEBUG_NIGHTVISION, effect_boomered, effect_contacts, effect_darkness, effect_in_pit, effect_narcosis, effect_no_sight, encumb(), flag_FIX_NEARSIGHT(), flag_IR_EFFECT(), flag_SWIM_GOGGLES(), get_per(), has_active_bionic(), has_active_mutation(), has_artifact_with(), has_bionic(), Creature::has_effect(), Creature::has_effect_with_flag(), has_nv(), has_trait(), in_sleep_state(), IR_VISION, is_blind(), is_mounted(), Creature::is_underwater(), is_wearing(), itype_rm13_armor_on, MF_MECH_RECON_VISION, mounted_creature, NV_GOGGLES, nv_range, vision::nv_range_from_eye_encumbrance(), vision::nv_range_from_per(), sight_max, trait_BIRD_EYE, trait_CEPH_EYES, trait_DEBUG_NIGHTVISION, trait_INFRARED, trait_LIZ_IR, trait_MEMBRANE, trait_MYOPIC, trait_PER_SLIME, trait_PER_SLIME_OK, trait_SEESLEEP, trait_SHELL2, trait_URSINE_EYE, URSINE_VISION, VISION_CLAIRVOYANCE, VISION_CLAIRVOYANCE_PLUS, VISION_CLAIRVOYANCE_SUPER, vision_mode_cache, and worn_with_flag().

Referenced by add_bionic(), deactivate_mutation(), environmental_revert_effect(), load(), game::load(), mount_creature(), mutation_spend_resources(), on_item_takeoff(), on_item_wear(), player::player(), remove_bionic(), reset_stats(), set_mutation(), set_underwater(), takeoff(), unset_mutation(), wake_up(), and wear_item().

◆ recalc_speed_bonus()

void Character::recalc_speed_bonus ( )

Calculates the various speed bonuses we will get from mutations, etc.

Definition at line 95 of file character_turn.cpp.

96{
97 // Minus some for weight...
98 int carry_penalty = 0;
99 if( weight_carried() > weight_capacity() && !has_trait( trait_id( "DEBUG_STORAGE" ) ) ) {
100 carry_penalty = 25 * ( weight_carried() - weight_capacity() ) / ( weight_capacity() );
101 }
102 mod_speed_bonus( -carry_penalty );
103
105
108 }
109 // when underweight, you get slower. cumulative with hunger
111
112 for( const auto &maps : *effects ) {
113 for( auto &i : maps.second ) {
114 if( i.second.is_removed() ) {
115 continue;
116 }
117 bool reduced = resists_effect( i.second );
118 mod_speed_bonus( i.second.get_mod( "SPEED", reduced ) );
119 }
120 }
121
122 // add martial arts speed bonus
124
125 // Not sure why Sunlight Dependent is here, but OK
126 // Ectothermic/COLDBLOOD4 is intended to buff folks in the Summer
127 // Threshold-crossing has its charms ;-)
128 if( g != nullptr ) {
129 if( has_trait( trait_SUNLIGHT_DEPENDENT ) && !g->is_in_sunlight( pos() ) ) {
130 mod_speed_bonus( -( g->light_level( posz() ) >= 12 ? 5 : 10 ) );
131 }
132 const float temperature_speed_modifier = mutation_value( "temperature_speed_modifier" );
133 if( temperature_speed_modifier != 0 ) {
134 const auto player_local_temp = get_weather().get_temperature( pos() );
135 if( has_trait( trait_COLDBLOOD4 ) || player_local_temp < 65 ) {
136 mod_speed_bonus( ( player_local_temp - 65 ) * temperature_speed_modifier );
137 }
138 }
139 }
140
142 mod_speed_bonus( 20 );
143 }
145 mod_speed_bonus( -20 );
146 }
147
148 float speed_modifier = Character::mutation_value( "speed_modifier" );
149 set_speed_bonus( static_cast<int>( get_speed() * speed_modifier ) - get_speed_base() );
150
151 if( has_bionic( bio_speed ) ) { // multiply by 1.1
152 set_speed_bonus( static_cast<int>( get_speed() * 1.1 ) - get_speed_base() );
153 }
154
155 double ench_bonus = enchantment_cache->calc_bonus( enchant_vals::mod::SPEED, get_speed() );
156 set_speed_bonus( get_speed() + ench_bonus - get_speed_base() );
157
158 // Speed cannot be less than 25% of base speed, so minimal speed bonus is -75% base speed.
159 const int min_speed_bonus = static_cast<int>( -0.75 * get_speed_base() );
160 if( get_speed_bonus() < min_speed_bonus ) {
161 set_speed_bonus( min_speed_bonus );
162 }
163}
static const trait_id trait_COLDBLOOD4("COLDBLOOD4")
static const trait_id trait_SUNLIGHT_DEPENDENT("SUNLIGHT_DEPENDENT")
static const bionic_id bio_speed("bio_speed")
int mabuff_speed_bonus() const
Returns the speed bonus from martial arts buffs.
virtual int get_speed_bonus() const
Definition: creature.cpp:1684
virtual void set_speed_bonus(int nspeed)
Definition: creature.cpp:1746
virtual void mod_speed_bonus(int nspeed)
Definition: creature.cpp:1763
virtual int get_speed_base() const
Definition: creature.cpp:1680
@ AEP_SPEED_UP
Definition: enums.h:107
@ AEP_SPEED_DOWN
Definition: enums.h:137
int get_thirst_speed_penalty(int thirst)
Returns the penalty to speed from thirst.
int get_kcal_speed_penalty(float kcal_percent)
Returns the penalty to speed from starvation.
stat_mod get_pain_penalty(const Character &ch)
Returns the effect of pain on stats.

References AEP_SPEED_DOWN, AEP_SPEED_UP, bio_speed, Creature::effects, enchantment_cache, g, get_kcal_percent(), character_effects::get_kcal_speed_penalty(), character_effects::get_pain_penalty(), get_speed(), Creature::get_speed_base(), Creature::get_speed_bonus(), weather_manager::get_temperature(), get_thirst(), character_effects::get_thirst_speed_penalty(), get_weather(), has_artifact_with(), has_bionic(), has_trait(), mabuff_speed_bonus(), Creature::mod_speed_bonus(), mutation_value(), pos(), posz(), Creature::resists_effect(), Creature::set_speed_bonus(), stat_mod::speed, enchant_vals::SPEED, trait_COLDBLOOD4, trait_id, trait_SUNLIGHT_DEPENDENT, very_thirsty, weight_capacity(), and weight_carried().

Referenced by reset_stats().

◆ recalculate_enchantment_cache()

void Character::recalculate_enchantment_cache ( )

Definition at line 7813 of file character.cpp.

7814{
7815 // start by resetting the cache
7817
7818 visit_items( [&]( const item * it ) {
7819 for( const enchantment &ench : it->get_enchantments() ) {
7820 if( ench.is_active( *this, *it ) ) {
7821 enchantment_cache->force_add( ench );
7822 }
7823 }
7824 return VisitResponse::NEXT;
7825 } );
7826
7827 // get from traits/ mutations
7828 for( const std::pair<const trait_id, char_trait_data> &mut_map : my_mutations ) {
7829 const mutation_branch &mut = mut_map.first.obj();
7830
7831 for( const enchantment_id &ench_id : mut.enchantments ) {
7832 const enchantment &ench = ench_id.obj();
7833 if( ench.is_active( *this, mut.activated && mut_map.second.powered ) ) {
7834 enchantment_cache->force_add( ench );
7835 }
7836 }
7837 }
7838
7839 for( const bionic &bio : *my_bionics ) {
7840 const bionic_id &bid = bio.id;
7841
7842 for( const enchantment_id &ench_id : bid->enchantments ) {
7843 const enchantment &ench = ench_id.obj();
7844 if( ench.is_active( *this, bio.powered &&
7845 bid->has_flag( STATIC( flag_str_id( "BIONIC_TOGGLED" ) ) ) ) ) {
7846 enchantment_cache->force_add( ench );
7847 }
7848 }
7849 }
7850
7852}
void rebuild_mutation_cache()
Definition: character.cpp:7854
bool is_active(const Character &guy, const item &parent) const
const std::vector< enchantment > & get_enchantments() const
Definition: item.cpp:6978
bool activated
Definition: mutation.h:93

References enchantment_cache, item::get_enchantments(), NEXT, and visitable< Character >::visit_items().

Referenced by activate_bionic(), activate_mutation(), add_bionic(), deactivate_bionic(), deactivate_mutation(), on_mutation_gain(), on_mutation_loss(), remove_bionic(), reset(), update_body(), and avatar_funcs::use_item().

◆ recalculate_size()

void Character::recalculate_size ( )

Recalculate size class of character.

Definition at line 246 of file mutation.cpp.

247{
249 // Only one size-changing mutation is expected, so it will only use the first one it finds.
250 for( const mutation_branch *mut : cached_mutations ) {
251 if( mut->body_size ) {
252 size_class = *mut->body_size;
253 break;
254 }
255 }
256}

References cached_mutations, MS_MEDIUM, and size_class.

Referenced by load(), mutation_effect(), and mutation_loss_effect().

◆ reduce_healing_effect()

int Character::reduce_healing_effect ( const efftype_id eff_id,
int  remove_med,
const bodypart_id hurt 
)

Reduce healing effect intensity, return initial intensity of the effect.

Definition at line 8575 of file character.cpp.

8577{
8578 const body_part hurt_token = hurt->token;
8579 effect &e = get_effect( eff_id, hurt_token );
8580 int intensity = e.get_intensity();
8581 if( remove_med < intensity ) {
8582 if( eff_id == effect_bandaged ) {
8583 add_msg_if_player( m_bad, _( "Bandages on your %s were damaged!" ), body_part_name( hurt_token ) );
8584 } else if( eff_id == effect_disinfected ) {
8585 add_msg_if_player( m_bad, _( "You got some filth on your disinfected %s!" ),
8586 body_part_name( hurt_token ) );
8587 }
8588 } else {
8589 if( eff_id == effect_bandaged ) {
8590 add_msg_if_player( m_bad, _( "Bandages on your %s were destroyed!" ),
8591 body_part_name( hurt_token ) );
8592 } else if( eff_id == effect_disinfected ) {
8593 add_msg_if_player( m_bad, _( "Your %s is no longer disinfected!" ), body_part_name( hurt_token ) );
8594 }
8595 }
8596 e.mod_duration( -6_hours * remove_med );
8597 return intensity;
8598}

References _, Creature::add_msg_if_player(), body_part_name(), effect_bandaged, effect_disinfected, Creature::get_effect(), effect::get_intensity(), m_bad, and effect::mod_duration().

Referenced by apply_damage().

◆ regen()

void Character::regen ( int  rate_multiplier)

Handles passive regeneration of pain and maybe hp.

Definition at line 4536 of file character.cpp.

4537{
4538 int pain_ticks = rate_multiplier;
4539 while( get_pain() > 0 && pain_ticks-- > 0 ) {
4540 mod_pain( -roll_remainder( ( 0.2f + get_pain() / 50.0f ) * ( 1.0f +
4541 mutation_value( "pain_recovery" ) ) ) );
4542 }
4543
4544 float rest = rest_quality();
4545 float heal_rate = healing_rate( rest ) * to_turns<int>( 5_minutes );
4546 if( heal_rate > 0.0f ) {
4547 healall( roll_remainder( rate_multiplier * heal_rate ) );
4548 } else if( heal_rate < 0.0f ) {
4549 int rot_rate = roll_remainder( rate_multiplier * -heal_rate );
4550 // Has to be in loop because some effects depend on rounding
4551 while( rot_rate-- > 0 ) {
4552 hurtall( 1, nullptr, false );
4553 }
4554 }
4555
4556 // include healing effects
4557 for( int i = 0; i < num_hp_parts; i++ ) {
4558 const bodypart_id &bp = convert_bp( hp_to_bp( static_cast<hp_part>( i ) ) ).id();
4559 float healing = healing_rate_medicine( rest, bp ) * to_turns<int>( 5_minutes );
4560
4561 int healing_apply = roll_remainder( healing );
4562 healed_bp( i, healing_apply );
4563 heal( bp, healing_apply );
4564 if( damage_bandaged[i] > 0 ) {
4565 damage_bandaged[i] -= healing_apply;
4566 if( damage_bandaged[i] <= 0 ) {
4567 damage_bandaged[i] = 0;
4568 remove_effect( effect_bandaged, bp->token );
4569 add_msg_if_player( _( "Bandaged wounds on your %s healed." ), body_part_name( bp ) );
4570 }
4571 }
4572 if( damage_disinfected[i] > 0 ) {
4573 damage_disinfected[i] -= healing_apply;
4574 if( damage_disinfected[i] <= 0 ) {
4575 damage_disinfected[i] = 0;
4576 remove_effect( effect_disinfected, bp->token );
4577 add_msg_if_player( _( "Disinfected wounds on your %s healed." ), body_part_name( bp ) );
4578 }
4579 }
4580
4581 // remove effects if the limb was healed by other way
4582 if( has_effect( effect_bandaged, bp->token ) && ( get_part( bp )->is_at_max_hp() ) ) {
4583 damage_bandaged[i] = 0;
4584 remove_effect( effect_bandaged, bp->token );
4585 add_msg_if_player( _( "Bandaged wounds on your %s healed." ), body_part_name( bp ) );
4586 }
4587 if( has_effect( effect_disinfected, bp->token ) && ( get_part( bp )->is_at_max_hp() ) ) {
4588 damage_disinfected[i] = 0;
4589 remove_effect( effect_disinfected, bp->token );
4590 add_msg_if_player( _( "Disinfected wounds on your %s healed." ), body_part_name( bp ) );
4591 }
4592 }
4593
4594 if( get_rad() > 0 ) {
4595 mod_rad( -roll_remainder( rate_multiplier / 50.0f ) );
4596 }
4597}
float healing_rate(float at_rest_quality) const
Average hit points healed per turn.
Definition: character.cpp:6618
float healing_rate_medicine(float at_rest_quality, const bodypart_id &bp) const
Average hit points healed per turn from healing effects.
Definition: character.cpp:6660
void healed_bp(int bp, int amount)
Definition: character.cpp:7701

References _, Creature::add_msg_if_player(), body_part_name(), convert_bp(), damage_bandaged, damage_disinfected, effect_bandaged, effect_disinfected, Creature::get_pain(), Creature::get_part(), get_rad(), Creature::has_effect(), heal(), healall(), healed_bp(), healing_rate(), healing_rate_medicine(), hp_to_bp(), hurtall(), string_id< T >::id(), mod_pain(), mod_rad(), mutation_value(), num_hp_parts, Creature::remove_effect(), rest_quality(), and roll_remainder().

Referenced by update_body().

◆ rem_addiction()

void Character::rem_addiction ( add_type  type)

Removes an addition from the player.

Definition at line 1950 of file suffer.cpp.

1951{
1952 auto iter = std::find_if( addictions.begin(), addictions.end(),
1953 [type]( const addiction & ad ) {
1954 return ad.type == type;
1955 } );
1956
1957 if( iter != addictions.end() ) {
1958 addictions.erase( iter );
1959 g->events().send<event_type::loses_addiction>( getID(), type );
1960 }
1961}

References addictions, g, getID(), loses_addiction, and type.

Referenced by marloss_common(), iuse::mycus(), and suffer_from_addictions().

◆ rem_morale()

void Character::rem_morale ( const morale_type type)

◆ remove_bionic()

void Character::remove_bionic ( const bionic_id b)

Removes a bionic from my_bionics[].

Definition at line 2573 of file bionics.cpp.

2574{
2575 bionic_collection new_my_bionics;
2576 // any spells you should not forget due to still having a bionic installed that has it.
2577 std::set<spell_id> cbm_spells;
2578 for( bionic &i : *my_bionics ) {
2579 if( b == i.id ) {
2580 continue;
2581 }
2582
2583 // Linked bionics: if either is removed, the other is removed as well.
2584 if( b->is_included( i.id ) || i.id->is_included( b ) ) {
2585 continue;
2586 }
2587
2588 for( const std::pair<const spell_id, int> &spell_pair : i.id->learned_spells ) {
2589 cbm_spells.emplace( spell_pair.first );
2590 }
2591
2592 new_my_bionics.push_back( bionic( i.id, i.invlet ) );
2593 }
2594
2595 // any spells you learn from installing a bionic you forget.
2596 for( const std::pair<const spell_id, int> &spell_pair : b->learned_spells ) {
2597 if( cbm_spells.count( spell_pair.first ) == 0 ) {
2598 magic->forget_spell( spell_pair.first );
2599 }
2600 }
2601
2602 *my_bionics = new_my_bionics;
2605 if( !b->enchantments.empty() ) {
2607 }
2608}

References b, magic, my_bionics, recalc_sight_limits(), recalculate_enchantment_cache(), and reset_encumbrance().

Referenced by perform_install(), perform_uninstall(), and uninstall_bionic().

◆ remove_child_flag()

void Character::remove_child_flag ( const trait_id flag)

Removes the mutation's child flag from the player's list.

Definition at line 1486 of file mutation.cpp.

1487{
1488 for( auto &elem : flag->replacements ) {
1489 const trait_id &tmp = elem;
1490 if( has_trait( tmp ) ) {
1491 remove_mutation( tmp );
1492 return;
1493 } else if( has_child_flag( tmp ) ) {
1494 remove_child_flag( tmp );
1495 return;
1496 }
1497 }
1498}

References has_child_flag(), has_trait(), remove_child_flag(), remove_mutation(), and mutation_branch::replacements.

Referenced by mutate_towards(), and remove_child_flag().

◆ remove_mission_items()

void Character::remove_mission_items ( int  mission_id)

Definition at line 2499 of file character.cpp.

2500{
2501 if( mission_id == -1 ) {
2502 return;
2503 }
2504 remove_items_with( has_mission_item_filter { mission_id } );
2505}

References visitable< Character >::remove_items_with().

◆ remove_mutation()

void Character::remove_mutation ( const trait_id mut,
bool  silent = false 
)

Removes a mutation, downgrading to the previous level if possible.

Definition at line 1328 of file mutation.cpp.

1329{
1330 const auto &mdata = mut.obj();
1331 // Check if there's a prerequisite we should shrink back into
1332 trait_id replacing = trait_id::NULL_ID();
1333 std::vector<trait_id> originals = mdata.prereqs;
1334 for( size_t i = 0; !replacing && i < originals.size(); i++ ) {
1335 trait_id pre = originals[i];
1336 const auto &p = pre.obj();
1337 for( size_t j = 0; !replacing && j < p.replacements.size(); j++ ) {
1338 if( p.replacements[j] == mut ) {
1339 replacing = pre;
1340 }
1341 }
1342 }
1343
1344 trait_id replacing2 = trait_id::NULL_ID();
1345 std::vector<trait_id> originals2 = mdata.prereqs2;
1346 for( size_t i = 0; !replacing2 && i < originals2.size(); i++ ) {
1347 trait_id pre2 = originals2[i];
1348 const auto &p = pre2.obj();
1349 for( size_t j = 0; !replacing2 && j < p.replacements.size(); j++ ) {
1350 if( p.replacements[j] == mut ) {
1351 replacing2 = pre2;
1352 }
1353 }
1354 }
1355
1356 // See if this mutation is canceled by a base trait
1357 //Only if there's no prerequisite to shrink to, thus we're at the bottom of the trait line
1358 if( !replacing ) {
1359 //Check each mutation until we reach the end or find a trait to revert to
1360 for( auto &iter : mutation_branch::get_all() ) {
1361 //See if it's in our list of base traits but not active
1362 if( has_base_trait( iter.id ) && !has_trait( iter.id ) ) {
1363 //See if that base trait cancels the mutation we are using
1364 std::vector<trait_id> traitcheck = iter.cancels;
1365 if( !traitcheck.empty() ) {
1366 for( size_t j = 0; !replacing && j < traitcheck.size(); j++ ) {
1367 if( traitcheck[j] == mut ) {
1368 replacing = ( iter.id );
1369 }
1370 }
1371 }
1372 }
1373 if( replacing ) {
1374 break;
1375 }
1376 }
1377 }
1378
1379 // Duplicated for prereq2
1380 if( !replacing2 ) {
1381 //Check each mutation until we reach the end or find a trait to revert to
1382 for( auto &iter : mutation_branch::get_all() ) {
1383 //See if it's in our list of base traits but not active
1384 if( has_base_trait( iter.id ) && !has_trait( iter.id ) ) {
1385 //See if that base trait cancels the mutation we are using
1386 std::vector<trait_id> traitcheck = iter.cancels;
1387 if( !traitcheck.empty() ) {
1388 for( size_t j = 0; !replacing2 && j < traitcheck.size(); j++ ) {
1389 if( traitcheck[j] == mut && ( iter.id ) != replacing ) {
1390 replacing2 = ( iter.id );
1391 }
1392 }
1393 }
1394 }
1395 if( replacing2 ) {
1396 break;
1397 }
1398 }
1399 }
1400
1401 // make sure we don't toggle a mutation or trait twice, or it will cancel itself out.
1402 if( replacing == replacing2 ) {
1403 replacing2 = trait_id::NULL_ID();
1404 }
1405
1406 // This should revert back to a removed base trait rather than simply removing the mutation
1407 unset_mutation( mut );
1408
1409 bool mutation_replaced = false;
1410
1411 game_message_type rating;
1412
1413 if( replacing ) {
1414 const auto &replace_mdata = replacing.obj();
1415 if( mdata.mixed_effect || replace_mdata.mixed_effect ) {
1416 rating = m_mixed;
1417 } else if( replace_mdata.points - mdata.points > 0 ) {
1418 rating = m_good;
1419 } else if( mdata.points - replace_mdata.points > 0 ) {
1420 rating = m_bad;
1421 } else {
1422 rating = m_neutral;
1423 }
1424 if( !silent ) {
1425 add_msg_player_or_npc( rating,
1426 _( "Your %1$s mutation turns into %2$s." ),
1427 _( "<npcname>'s %1$s mutation turns into %2$s." ),
1428 mdata.name(), replace_mdata.name() );
1429 }
1430 set_mutation( replacing );
1431 mutation_replaced = true;
1432 }
1433 if( replacing2 ) {
1434 const auto &replace_mdata = replacing2.obj();
1435 if( mdata.mixed_effect || replace_mdata.mixed_effect ) {
1436 rating = m_mixed;
1437 } else if( replace_mdata.points - mdata.points > 0 ) {
1438 rating = m_good;
1439 } else if( mdata.points - replace_mdata.points > 0 ) {
1440 rating = m_bad;
1441 } else {
1442 rating = m_neutral;
1443 }
1444 if( !silent ) {
1445 add_msg_player_or_npc( rating,
1446 _( "Your %1$s mutation turns into %2$s." ),
1447 _( "<npcname>'s %1$s mutation turns into %2$s." ),
1448 mdata.name(), replace_mdata.name() );
1449 }
1450 set_mutation( replacing2 );
1451 mutation_replaced = true;
1452 }
1453 if( !mutation_replaced ) {
1454 if( mdata.mixed_effect ) {
1455 rating = m_mixed;
1456 } else if( mdata.points > 0 ) {
1457 rating = m_bad;
1458 } else if( mdata.points < 0 ) {
1459 rating = m_good;
1460 } else {
1461 rating = m_neutral;
1462 }
1463 if( !silent ) {
1464 add_msg_player_or_npc( rating,
1465 _( "You lose your %s mutation." ),
1466 _( "<npcname> loses their %s mutation." ),
1467 mdata.name() );
1468 }
1469 }
1470
1473}
@ silent
Definition: weather_type.h:56

References _, Creature::add_msg_player_or_npc(), drench_mut_calc(), mutation_branch::get_all(), has_base_trait(), has_trait(), m_bad, m_good, m_mixed, m_neutral, string_id< mutation_branch >::NULL_ID(), string_id< T >::obj(), set_highest_cat_level(), set_mutation(), silent, and unset_mutation().

Referenced by do_purify(), player::load(), mutate(), mutate_towards(), old_mutate(), perform_install(), iuse::purify_iv(), iuse::purify_smart(), remove_child_flag(), and debug_menu::wishmutate().

◆ remove_weapon()

item Character::remove_weapon ( )

Definition at line 2486 of file character.cpp.

2487{
2488 item tmp = weapon;
2489 weapon = item();
2490 clear_npc_ai_info_cache( "weapon_value" );
2491 return tmp;
2492}

References clear_npc_ai_info_cache(), and weapon.

Referenced by talk_function::drop_weapon(), melee_special_effects(), perform_technique(), mattack::pull_metal_weapon(), smash(), npc::stow_item(), and use_amount().

◆ remove_worn_items_with()

std::list< item > Character::remove_worn_items_with ( std::function< bool(item &)>  filter)

Similar to remove_items_with, but considers only worn items and not their content (item::contents is not checked).

If the filter function returns true, the item is removed.

Definition at line 2265 of file character.cpp.

2266{
2267 std::list<item> result;
2268 for( auto iter = worn.begin(); iter != worn.end(); ) {
2269 if( filter( *iter ) ) {
2270 iter->on_takeoff( *this );
2271 result.splice( result.begin(), worn, iter++ );
2272 } else {
2273 ++iter;
2274 }
2275 }
2276 return result;
2277}

References worn.

Referenced by mutation_effect(), and process_items().

◆ reset()

void Character::reset ( )
overridevirtual

Handles stat and bonus reset.

Reimplemented from Creature.

Definition at line 3610 of file character.cpp.

3611{
3613 // TODO: Move reset_stats here, remove it from Creature
3615}
virtual void reset()
Handles stat and bonus reset.
Definition: creature.cpp:121

References recalculate_enchantment_cache(), and Creature::reset().

Referenced by activate_bionic(), deactivate_bionic(), game::load(), and set_stats().

◆ reset_bonuses()

void Character::reset_bonuses ( )
overridevirtual

Resets the value of all bonus fields to 0.

Reimplemented from Creature.

Definition at line 4513 of file character.cpp.

4514{
4515 // Reset all bonuses to 0 and multipliers to 1.0
4516 str_bonus = 0;
4517 dex_bonus = 0;
4518 per_bonus = 0;
4519 int_bonus = 0;
4520
4522}
virtual void reset_bonuses()
Resets the value of all bonus fields to 0.
Definition: creature.cpp:135

References dex_bonus, int_bonus, per_bonus, Creature::reset_bonuses(), and str_bonus.

◆ reset_chargen_attributes()

void Character::reset_chargen_attributes ( )

Definition at line 6734 of file character.cpp.

6735{
6736 init_age = 25;
6737 init_height = 175;
6738}

References init_age, and init_height.

◆ reset_encumbrance()

◆ reset_remote_fuel()

void Character::reset_remote_fuel ( )

Definition at line 1444 of file bionics.cpp.

1445{
1446 if( get_bionic_fueled_with( item( fuel_type_sun_light ) ).empty() ) {
1447 remove_value( "sunlight" );
1448 }
1449 remove_value( "rem_battery" );
1450}

References fuel_type_sun_light, get_bionic_fueled_with(), and Creature::remove_value().

Referenced by iuse::cable_attach(), and deactivate_bionic().

◆ reset_stats()

void Character::reset_stats ( )
overridevirtual

Resets stats, and applies effects in an idempotent manner.

Implements Creature.

Definition at line 580 of file character_turn.cpp.

581{
582 const int current_stim = get_stim();
583
584 // Trait / mutation buffs
586 add_miss_reason( _( "Your thick scales get in the way." ), 2 );
587 }
589 add_miss_reason( _( "Your chitin gets in the way." ), 1 );
590 }
592 mod_per_bonus( 2 );
593 }
595 add_miss_reason( _( "Your insect limbs get in the way." ), 2 );
596 }
598 if( !wearing_something_on( bodypart_id( "torso" ) ) ) {
599 mod_dex_bonus( 1 );
600 } else {
601 mod_dex_bonus( -1 );
602 add_miss_reason( _( "Your clothing restricts your insect arms." ), 1 );
603 }
604 }
605 if( has_trait( trait_WEBBED ) ) {
606 add_miss_reason( _( "Your webbed hands get in the way." ), 1 );
607 }
609 add_miss_reason( _( "Your arachnid limbs get in the way." ), 4 );
610 }
612 if( !wearing_something_on( bodypart_id( "torso" ) ) ) {
613 mod_dex_bonus( 2 );
614 } else if( !exclusive_flag_coverage( "OVERSIZE" ).test( bp_torso ) ) {
615 mod_dex_bonus( -2 );
616 add_miss_reason( _( "Your clothing constricts your arachnid limbs." ), 2 );
617 }
618 }
619 const auto set_fake_effect_dur = [this]( const efftype_id & type, const time_duration & dur ) {
620 effect &eff = get_effect( type );
621 if( eff.get_duration() == dur ) {
622 return;
623 }
624
625 if( eff.is_null() && dur > 0_turns ) {
626 add_effect( type, dur, num_bp );
627 } else if( dur > 0_turns ) {
628 eff.set_duration( dur );
629 } else {
631 }
632 };
633 // Painkiller
634 set_fake_effect_dur( effect_pkill, 1_turns * get_painkiller() );
635
636 // Pain
637 if( get_perceived_pain() > 0 ) {
638 const stat_mod ppen = character_effects::get_pain_penalty( *this );
639 mod_str_bonus( -ppen.strength );
640 mod_dex_bonus( -ppen.dexterity );
642 mod_per_bonus( -ppen.perception );
643 if( ppen.dexterity > 0 ) {
644 add_miss_reason( _( "Your pain distracts you!" ), static_cast<unsigned>( ppen.dexterity ) );
645 }
646 }
647
648 // Radiation
649 set_fake_effect_dur( effect_irradiated, 1_turns * get_rad() );
650 // Morale
651 const int morale = get_morale_level();
652 set_fake_effect_dur( effect_happy, 1_turns * morale );
653 set_fake_effect_dur( effect_sad, 1_turns * -morale );
654
655 // Stimulants
656 set_fake_effect_dur( effect_stim, 1_turns * current_stim );
657 set_fake_effect_dur( effect_depressants, 1_turns * -current_stim );
658 if( has_trait( trait_STIMBOOST ) ) {
659 set_fake_effect_dur( effect_stim_overdose, 1_turns * ( current_stim - 60 ) );
660 } else {
661 set_fake_effect_dur( effect_stim_overdose, 1_turns * ( current_stim - 30 ) );
662 }
663 // Starvation
664 if( get_kcal_percent() < 0.95f ) {
665 // kcal->percentage of base str
666 static const std::vector<std::pair<float, float>> starv_thresholds = { {
667 std::make_pair( 0.0f, 0.5f ),
668 std::make_pair( 0.8f, 0.1f ),
669 std::make_pair( 0.95f, 0.0f )
670 }
671 };
672
673 const int str_penalty = std::floor( multi_lerp( starv_thresholds, get_kcal_percent() ) );
674 add_miss_reason( _( "You're weak from hunger." ),
675 static_cast<unsigned>( str_penalty / 2 ) );
676 mod_str_bonus( -str_penalty );
677 mod_dex_bonus( -( str_penalty / 2 ) );
678 mod_int_bonus( -( str_penalty / 2 ) );
679 }
680 // Thirst
681 set_fake_effect_dur( effect_thirsty, 1_turns * ( get_thirst() - thirst_levels::very_thirsty ) );
683 set_fake_effect_dur( effect_sleep_deprived, 1_turns * get_sleep_deprivation() );
684 } else if( has_effect( effect_sleep_deprived ) ) {
686 }
687
688 // Dodge-related effects
690 ( encumb( bp_leg_l ) + encumb( bp_leg_r ) ) / 20.0f - encumb( bp_torso ) / 10.0f );
691 // Whiskers don't work so well if they're covered
692 if( has_trait( trait_WHISKERS ) && !wearing_something_on( bodypart_id( "mouth" ) ) ) {
693 mod_dodge_bonus( 1.5 );
694 }
696 mod_dodge_bonus( 3 );
697 }
698 // depending on mounts size, attacks will hit the mount and use their dodge rating.
699 // if they hit the player, the player cannot dodge as effectively.
700 if( is_mounted() ) {
701 mod_dodge_bonus( -4 );
702 }
703 // Spider hair is basically a full-body set of whiskers, once you get the brain for it
705 static const std::array<bodypart_id, 5> parts{ { bodypart_id( "head" ), bodypart_id( "arm_r" ), bodypart_id( "arm_l" ), bodypart_id( "leg_r" ), bodypart_id( "leg_l" ) } };
706 for( const bodypart_id &bp : parts ) {
707 if( !wearing_something_on( bp ) ) {
708 mod_dodge_bonus( +1 );
709 }
710 }
711 // Torso handled separately, bigger bonus
712 if( !wearing_something_on( bodypart_id( "torso" ) ) ) {
713 mod_dodge_bonus( 4 );
714 }
715 }
716
717 // Apply static martial arts buffs
718 martial_arts_data->ma_static_effects( *this );
719
720 if( calendar::once_every( 1_minutes ) ) {
722 }
723
724 // Effects
725 for( const auto &maps : *effects ) {
726 for( auto i : maps.second ) {
727 const auto &it = i.second;
728 if( it.is_removed() ) {
729 continue;
730 }
731 bool reduced = resists_effect( it );
732 mod_str_bonus( it.get_mod( "STR", reduced ) );
733 mod_dex_bonus( it.get_mod( "DEX", reduced ) );
734 mod_per_bonus( it.get_mod( "PER", reduced ) );
735 mod_int_bonus( it.get_mod( "INT", reduced ) );
736 }
737 }
738
739 // Bionic buffs
741 mod_str_bonus( 20 );
742 }
743
748
749 // Trait / mutation buffs
750 mod_str_bonus( std::floor( mutation_value( "str_modifier" ) ) );
751 mod_dodge_bonus( std::floor( mutation_value( "dodge_modifier" ) ) );
752
754
755 nv_cached = false;
756
757 // Reset our stats to normal levels
758 // Any persistent buffs/debuffs will take place in effects,
759 // player::suffer(), etc.
760
761 // repopulate the stat fields
766
767 // Floor for our stats. No stat changes should occur after this!
768 if( dex_cur < 0 ) {
769 dex_cur = 0;
770 }
771 if( str_cur < 0 ) {
772 str_cur = 0;
773 }
774 if( per_cur < 0 ) {
775 per_cur = 0;
776 }
777 if( int_cur < 0 ) {
778 int_cur = 0;
779 }
780
783}
float multi_lerp(const std::vector< std::pair< float, float > > &points, float x)
From points, finds p1 and p2 such that p1.first < x < p2.first Then linearly interpolates between p1....
static const efftype_id effect_sad("sad")
static const efftype_id effect_pkill("pkill")
static const trait_id trait_ARACHNID_ARMS("ARACHNID_ARMS")
static const trait_id trait_THICK_SCALES("THICK_SCALES")
static const trait_id trait_COMPOUND_EYES("COMPOUND_EYES")
static const trait_id trait_WEBBED("WEBBED")
static const bionic_id bio_hydraulics("bio_hydraulics")
static const efftype_id effect_irradiated("irradiated")
static const trait_id trait_CHITIN3("CHITIN3")
static const trait_id trait_CHITIN2("CHITIN2")
static const trait_id trait_STIMBOOST("STIMBOOST")
static const trait_id trait_CHITIN_FUR3("CHITIN_FUR3")
static const trait_id trait_WHISKERS("WHISKERS")
static const efftype_id effect_thirsty("thirsty")
static const trait_id trait_WHISKERS_RAT("WHISKERS_RAT")
static const trait_id trait_INSECT_ARMS_OK("INSECT_ARMS_OK")
static const trait_id trait_ARACHNID_ARMS_OK("ARACHNID_ARMS_OK")
static const efftype_id effect_stim_overdose("stim_overdose")
static const efftype_id effect_stim("stim")
static const efftype_id effect_happy("happy")
static const efftype_id effect_depressants("depressants")
static const efftype_id effect_sleep_deprived("sleep_deprived")
static const trait_id trait_INSECT_ARMS("INSECT_ARMS")
virtual int get_str_bonus() const
Definition: character.cpp:4086
virtual int get_int_bonus() const
Definition: character.cpp:4098
int get_mod_stat_from_bionic(const character_stat &Stat) const
Get stat bonus from bionic.
Definition: character.cpp:2087
float mabuff_dodge_bonus() const
Returns the dodge bonus from martial arts buffs.
virtual int get_per_bonus() const
Definition: character.cpp:4094
void apply_skill_boost()
Applies skill-based boosts to stats.
Definition: character.cpp:3533
void recalc_speed_bonus()
Calculates the various speed bonuses we will get from mutations, etc.
virtual int get_dex_bonus() const
Definition: character.cpp:4090
virtual void mod_dodge_bonus(float ndodge)
Definition: creature.cpp:1767
void update_mental_focus(Character &who)
Uses calc_focus_change to update the player's current focus.

References _, Creature::add_effect(), add_miss_reason(), apply_skill_boost(), bio_hydraulics, bp_leg_l, bp_leg_r, bp_torso, dex_cur, dex_max, stat_mod::dexterity, DEXTERITY, effect_depressants, effect_happy, effect_irradiated, effect_pkill, effect_sad, effect_sleep_deprived, effect_stim, effect_stim_overdose, effect_thirsty, Creature::effects, encumb(), exclusive_flag_coverage(), get_dex_bonus(), effect::get_duration(), Creature::get_effect(), get_int_bonus(), get_kcal_percent(), get_mod_stat_from_bionic(), get_morale_level(), character_effects::get_pain_penalty(), get_painkiller(), get_per_bonus(), get_perceived_pain(), get_rad(), get_sleep_deprivation(), get_stim(), get_str_bonus(), get_thirst(), harmless, has_active_bionic(), Creature::has_effect(), has_trait(), int_cur, int_max, stat_mod::intelligence, INTELLIGENCE, is_mounted(), effect::is_null(), mabuff_dodge_bonus(), martial_arts_data, mod_dex_bonus(), Creature::mod_dodge_bonus(), mod_int_bonus(), mod_per_bonus(), mod_str_bonus(), morale, multi_lerp(), mutation_value(), num_bp, nv_cached, calendar::once_every(), per_cur, per_max, stat_mod::perception, PERCEPTION, recalc_sight_limits(), recalc_speed_bonus(), Creature::remove_effect(), Creature::resists_effect(), effect::set_duration(), str_cur, str_max, stat_mod::strength, STRENGTH, trait_ARACHNID_ARMS, trait_ARACHNID_ARMS_OK, trait_CHITIN2, trait_CHITIN3, trait_CHITIN_FUR3, trait_COMPOUND_EYES, trait_INSECT_ARMS, trait_INSECT_ARMS_OK, trait_STIMBOOST, trait_THICK_SCALES, trait_WEBBED, trait_WHISKERS, trait_WHISKERS_RAT, type, character_funcs::update_mental_focus(), very_thirsty, and wearing_something_on().

Referenced by debug_menu::character_edit_menu().

◆ rest_quality()

float Character::rest_quality ( ) const

Returns >0 if character is sitting/lying and relatively inactive.

1 represents sleep on comfortable bed, so anything above that should be rare.

Definition at line 6410 of file character.cpp.

6411{
6412 // Just a placeholder for now.
6413 // TODO: Waiting/reading/being unconscious on bed/sofa/grass
6414 return has_effect( effect_sleep ) ? 1.0f : 0.0f;
6415}

References effect_sleep, and Creature::has_effect().

Referenced by mend(), and regen().

◆ restore_scent()

void Character::restore_scent ( )

restore scent after masked_scent effect run out or is removed by water

Definition at line 8720 of file character.cpp.

8721{
8722 const std::string prev_scent = get_value( "prev_scent" );
8723 if( !prev_scent.empty() ) {
8725 set_type_of_scent( scenttype_id( prev_scent ) );
8726 remove_value( "prev_scent" );
8727 remove_value( "waterproof_scent" );
8728 add_msg_if_player( m_info, _( "You smell like yourself again." ) );
8729 }
8730}
static const efftype_id effect_masked_scent("masked_scent")
void set_type_of_scent(const scenttype_id &id)
Definition: character.cpp:8710
string_id< scent_type > scenttype_id
Definition: type_id.h:42

References _, Creature::add_msg_if_player(), effect_masked_scent, Creature::get_value(), m_info, Creature::remove_effect(), Creature::remove_value(), and set_type_of_scent().

Referenced by drench(), and process_turn().

◆ resume_backlog_activity()

void Character::resume_backlog_activity ( )

Definition at line 9220 of file character.cpp.

9221{
9222 if( !backlog.empty() && backlog.front().auto_resume ) {
9223 activity = backlog.front();
9224 backlog.pop_front();
9225 }
9226}

References activity, and backlog.

Referenced by game::cancel_activity_query(), and player_activity::do_turn().

◆ roll_all_damage()

void Character::roll_all_damage ( bool  crit,
damage_instance di,
bool  average,
const item weap 
) const

Adds all 3 types of physical damage to instance.

Definition at line 354 of file melee.cpp.

356{
357 roll_bash_damage( crit, di, average, weap );
358 roll_cut_damage( crit, di, average, weap );
359 roll_stab_damage( crit, di, average, weap );
360}
void roll_stab_damage(bool crit, damage_instance &di, bool average, const item &weap) const
Adds player's total stab damage to the damage instance.
Definition: melee.cpp:1050
void roll_bash_damage(bool crit, damage_instance &di, bool average, const item &weap) const
Adds player's total bash damage to the damage instance.
Definition: melee.cpp:872
void roll_cut_damage(bool crit, damage_instance &di, bool average, const item &weap) const
Adds player's total cut damage to the damage instance.
Definition: melee.cpp:976

References roll_bash_damage(), roll_cut_damage(), and roll_stab_damage().

Referenced by item::combat_info(), item::effective_dps(), and melee_attack().

◆ roll_bash_damage()

void Character::roll_bash_damage ( bool  crit,
damage_instance di,
bool  average,
const item weap 
) const

Adds player's total bash damage to the damage instance.

Strength increases bashing damage Strength increases bashing damage Unarmed caps bash damage with unarmed weapons Bashing caps bash damage with bashing weapons Strength boosts low cap on bashing damage

Definition at line 872 of file melee.cpp.

874{
875 float bash_dam = 0.0f;
876
877 const bool unarmed = weap.is_unarmed_weapon();
878 int skill = get_skill_level( unarmed ? skill_unarmed : skill_bashing );
879 if( has_active_bionic( bio_cqb ) ) {
880 skill = BIO_CQB_LEVEL;
881 }
882
883 const int stat = get_str();
884 /** @EFFECT_STR increases bashing damage */
885 float stat_bonus = bonus_damage( !average );
886 stat_bonus += mabuff_damage_bonus( DT_BASH );
887
888 // Drunken Master damage bonuses
890 // Remember, a single drink gives 600 levels of "drunk"
891 int mindrunk = 0;
892 int maxdrunk = 0;
893 const time_duration drunk_dur = get_effect_dur( effect_drunk );
894 if( unarmed ) {
895 mindrunk = drunk_dur / 1_hours;
896 maxdrunk = drunk_dur / 25_minutes;
897 } else {
898 mindrunk = drunk_dur / 90_minutes;
899 maxdrunk = drunk_dur / 40_minutes;
900 }
901
902 bash_dam += average ? ( mindrunk + maxdrunk ) * 0.5f : rng( mindrunk, maxdrunk );
903 }
904
905 if( unarmed ) {
906 const bool left_empty = !natural_attack_restricted_on( bodypart_id( "hand_l" ) );
907 const bool right_empty = !natural_attack_restricted_on( bodypart_id( "hand_r" ) ) &&
908 weap.is_null();
909 if( left_empty || right_empty ) {
910 float per_hand = 0.0f;
911 for( const trait_id &mut : get_mutations() ) {
912 if( mut->flags.count( "NEED_ACTIVE_TO_MELEE" ) > 0 && !has_active_mutation( mut ) ) {
913 continue;
914 }
915 float unarmed_bonus = 0.0f;
916 const int bash_bonus = mut->bash_dmg_bonus;
917 if( mut->flags.count( "UNARMED_BONUS" ) > 0 && bash_bonus > 0 ) {
918 unarmed_bonus += std::min( get_skill_level( skill_unarmed ) / 2, 4 );
919 }
920 per_hand += bash_bonus + unarmed_bonus;
921 const std::pair<int, int> rand_bash = mut->rand_bash_bonus;
922 per_hand += average ? ( rand_bash.first + rand_bash.second ) / 2.0f : rng( rand_bash.first,
923 rand_bash.second );
924 }
925 bash_dam += per_hand; // First hand
926 if( left_empty && right_empty ) {
927 // Second hand
928 bash_dam += per_hand;
929 }
930 }
931
932 }
933
934 /** @EFFECT_STR increases bashing damage */
935 float weap_dam = weap.damage_melee( DT_BASH ) + stat_bonus;
936 /** @EFFECT_UNARMED caps bash damage with unarmed weapons */
937
938 /** @EFFECT_BASHING caps bash damage with bashing weapons */
939 float bash_cap = 2 * stat + 2 * skill;
940 float bash_mul = 1.0f;
941
942 // 80%, 88%, 96%, 104%, 112%, 116%, 120%, 124%, 128%, 132%
943 if( skill < 5 ) {
944 bash_mul = 0.8 + 0.08 * skill;
945 } else {
946 bash_mul = 0.96 + 0.04 * skill;
947 }
948
949 if( bash_cap < weap_dam && !weap.is_null() ) {
950 // If damage goes over cap due to low stats/skills,
951 // scale the post-armor damage down halfway between damage and cap
952 bash_mul *= ( 1.0f + ( bash_cap / weap_dam ) ) / 2.0f;
953 }
954
955 /** @EFFECT_STR boosts low cap on bashing damage */
956 const float low_cap = std::min( 1.0f, stat / 20.0f );
957 const float bash_min = low_cap * weap_dam;
958 weap_dam = average ? ( bash_min + weap_dam ) * 0.5f : rng_float( bash_min, weap_dam );
959
960 bash_dam += weap_dam;
961 bash_mul *= mabuff_damage_mult( DT_BASH );
962
963 float armor_mult = 1.0f;
964 int arpen = mabuff_arpen_bonus( DT_BASH );
965
966 // Finally, extra critical effects
967 if( crit ) {
968 bash_mul *= 1.5f;
969 // 50% armor penetration
970 armor_mult = 0.5f;
971 }
972
973 di.add_damage( DT_BASH, bash_dam, arpen, armor_mult, bash_mul );
974}
int mabuff_arpen_bonus(damage_type type) const
Returns the arpen bonus from martial arts buffs.
float bonus_damage(bool random) const
Returns the bonus bashing damage the player deals based on their stats.
Definition: melee.cpp:862
bool natural_attack_restricted_on(const bodypart_id &bp) const
Returns true if the character is wearing something on the entered body_part, ignoring items with the ...
Definition: character.cpp:1763
int mabuff_damage_bonus(damage_type type) const
Returns the flat damage bonus to given type from martial arts buffs, applied after the multiplier.
float mabuff_damage_mult(damage_type type) const
Returns the damage multiplier to given type from martial arts buffs.
static const efftype_id effect_drunk("drunk")
static const trait_id trait_DRUNKEN("DRUNKEN")
static const skill_id skill_bashing("bashing")

References damage_instance::add_damage(), bio_cqb, BIO_CQB_LEVEL, bonus_damage(), item::damage_melee(), DT_BASH, effect_drunk, Creature::get_effect_dur(), get_mutations(), get_skill_level(), get_str(), has_active_bionic(), has_active_mutation(), Creature::has_effect(), has_trait(), item::is_null(), item::is_unarmed_weapon(), mabuff_arpen_bonus(), mabuff_damage_bonus(), mabuff_damage_mult(), natural_attack_restricted_on(), rng(), rng_float(), skill_bashing, skill_unarmed, and trait_DRUNKEN.

Referenced by roll_all_damage().

◆ roll_cut_damage()

void Character::roll_cut_damage ( bool  crit,
damage_instance di,
bool  average,
const item weap 
) const

Adds player's total cut damage to the damage instance.

Cutting increases cutting damage multiplier

Definition at line 976 of file melee.cpp.

978{
979 float cut_dam = mabuff_damage_bonus( DT_CUT ) + weap.damage_melee( DT_CUT );
980 float cut_mul = 1.0f;
981
982 int cutting_skill = get_skill_level( skill_cutting );
983
984 if( has_active_bionic( bio_cqb ) ) {
985 cutting_skill = BIO_CQB_LEVEL;
986 }
987
988 if( weap.is_unarmed_weapon() ) {
989 // TODO: 1-handed weapons that aren't unarmed attacks
990 const bool left_empty = !natural_attack_restricted_on( bodypart_id( "hand_l" ) );
991 const bool right_empty = !natural_attack_restricted_on( bodypart_id( "hand_r" ) ) &&
992 weap.is_null();
993 if( left_empty || right_empty ) {
994 float per_hand = 0.0f;
995 if( has_bionic( bionic_id( "bio_razors" ) ) ) {
996 per_hand += 2;
997 }
998
999 for( const trait_id &mut : get_mutations() ) {
1000 if( mut->flags.count( "NEED_ACTIVE_TO_MELEE" ) > 0 && !has_active_mutation( mut ) ) {
1001 continue;
1002 }
1003 float unarmed_bonus = 0.0f;
1004 const int cut_bonus = mut->cut_dmg_bonus;
1005 if( mut->flags.count( "UNARMED_BONUS" ) > 0 && cut_bonus > 0 ) {
1006 unarmed_bonus += std::min( get_skill_level( skill_unarmed ) / 2, 4 );
1007 }
1008 per_hand += cut_bonus + unarmed_bonus;
1009 const std::pair<int, int> rand_cut = mut->rand_cut_bonus;
1010 per_hand += average ? ( rand_cut.first + rand_cut.second ) / 2.0f : rng( rand_cut.first,
1011 rand_cut.second );
1012 }
1013 // TODO: add acidproof check back to slime hands (probably move it elsewhere)
1014
1015 cut_dam += per_hand; // First hand
1016 if( left_empty && right_empty ) {
1017 // Second hand
1018 cut_dam += per_hand;
1019 }
1020 }
1021 }
1022
1023 if( cut_dam <= 0.0f ) {
1024 return; // No negative damage!
1025 }
1026
1027 int arpen = 0;
1028 float armor_mult = 1.0f;
1029
1030 // 80%, 88%, 96%, 104%, 112%, 116%, 120%, 124%, 128%, 132%
1031 /** @EFFECT_CUTTING increases cutting damage multiplier */
1032 if( cutting_skill < 5 ) {
1033 cut_mul *= 0.8 + 0.08 * cutting_skill;
1034 } else {
1035 cut_mul *= 0.96 + 0.04 * cutting_skill;
1036 }
1037
1038 arpen += mabuff_arpen_bonus( DT_CUT );
1039
1040 cut_mul *= mabuff_damage_mult( DT_CUT );
1041 if( crit ) {
1042 cut_mul *= 1.25f;
1043 arpen += 5;
1044 armor_mult = 0.75f; //25% armor penetration
1045 }
1046
1047 di.add_damage( DT_CUT, cut_dam, arpen, armor_mult, cut_mul );
1048}
static const skill_id skill_cutting("cutting")

References damage_instance::add_damage(), bio_cqb, BIO_CQB_LEVEL, bionic_id, item::damage_melee(), DT_CUT, get_mutations(), get_skill_level(), has_active_bionic(), has_active_mutation(), has_bionic(), item::is_null(), item::is_unarmed_weapon(), mabuff_arpen_bonus(), mabuff_damage_bonus(), mabuff_damage_mult(), natural_attack_restricted_on(), rng(), skill_cutting, and skill_unarmed.

Referenced by roll_all_damage().

◆ roll_stab_damage()

void Character::roll_stab_damage ( bool  crit,
damage_instance di,
bool  average,
const item weap 
) const

Adds player's total stab damage to the damage instance.

Stabbing increases stabbing damage multiplier

Definition at line 1050 of file melee.cpp.

1052{
1053 float stab_dam = mabuff_damage_bonus( DT_STAB ) + weap.damage_melee( DT_STAB );
1054
1055 int unarmed_skill = get_skill_level( skill_unarmed );
1056 int stabbing_skill = get_skill_level( skill_stabbing );
1057
1058 if( has_active_bionic( bio_cqb ) ) {
1059 stabbing_skill = BIO_CQB_LEVEL;
1060 }
1061
1062 if( weap.is_unarmed_weapon() ) {
1063 const bool left_empty = !natural_attack_restricted_on( bodypart_id( "hand_l" ) );
1064 const bool right_empty = !natural_attack_restricted_on( bodypart_id( "hand_r" ) ) &&
1065 weap.is_null();
1066 if( left_empty || right_empty ) {
1067 float per_hand = 0.0f;
1068
1069 for( const trait_id &mut : get_mutations() ) {
1070 int stab_bonus = mut->pierce_dmg_bonus;
1071 int unarmed_bonus = 0;
1072 if( mut->flags.count( "UNARMED_BONUS" ) > 0 && stab_bonus > 0 ) {
1073 unarmed_bonus = std::min( unarmed_skill / 2, 4 );
1074 }
1075
1076 per_hand += stab_bonus + unarmed_bonus;
1077 }
1078
1079 if( has_bionic( bionic_id( "bio_razors" ) ) ) {
1080 per_hand += 2;
1081 }
1082
1083 stab_dam += per_hand; // First hand
1084 if( left_empty && right_empty ) {
1085 // Second hand
1086 stab_dam += per_hand;
1087 }
1088 }
1089 }
1090
1091 if( stab_dam <= 0 ) {
1092 return; // No negative stabbing!
1093 }
1094
1095 float stab_mul = 1.0f;
1096 // 66%, 76%, 86%, 96%, 106%, 116%, 122%, 128%, 134%, 140%
1097 /** @EFFECT_STABBING increases stabbing damage multiplier */
1098 if( stabbing_skill <= 5 ) {
1099 stab_mul = 0.66 + 0.1 * stabbing_skill;
1100 } else {
1101 stab_mul = 0.86 + 0.06 * stabbing_skill;
1102 }
1103 int arpen = mabuff_arpen_bonus( DT_STAB );
1104 stab_mul *= mabuff_damage_mult( DT_STAB );
1105 float armor_mult = 1.0f;
1106
1107 if( crit ) {
1108 // Critical damage bonus for stabbing scales with skill
1109 stab_mul *= 1.0 + ( stabbing_skill / 10.0 );
1110 // Stab criticals have extra %arpen
1111 armor_mult = 0.66f;
1112 }
1113
1114 di.add_damage( DT_STAB, stab_dam, arpen, armor_mult, stab_mul );
1115}

References damage_instance::add_damage(), bio_cqb, BIO_CQB_LEVEL, bionic_id, item::damage_melee(), DT_STAB, get_mutations(), get_skill_level(), has_active_bionic(), has_bionic(), item::is_null(), item::is_unarmed_weapon(), mabuff_arpen_bonus(), mabuff_damage_bonus(), mabuff_damage_mult(), natural_attack_restricted_on(), skill_stabbing, and skill_unarmed.

Referenced by roll_all_damage().

◆ rooted()

void Character::rooted ( )

Definition at line 8798 of file character.cpp.

8800{
8801 double shoe_factor = footwear_factor();
8802 if( ( has_trait( trait_ROOTS2 ) || has_trait( trait_ROOTS3 ) ) &&
8803 get_map().has_flag( flag_PLOWABLE, pos() ) && shoe_factor != 1.0 ) {
8804 if( one_in( 96 ) ) {
8805 vitamin_mod( vitamin_id( "iron" ), 1, true );
8806 vitamin_mod( vitamin_id( "calcium" ), 1, true );
8807 }
8808 if( get_thirst() <= thirst_levels::turgid && x_in_y( 75, 425 ) ) {
8809 mod_thirst( -1 );
8810 }
8811 mod_healthy_mod( 5, 50 );
8812 }
8813}
static const std::string flag_PLOWABLE("PLOWABLE")
int vitamin_mod(const vitamin_id &vit, int qty, bool capped=true)
Add or subtract vitamins from character storage pools.
string_id< vitamin > vitamin_id
Definition: type_id.h:187

References flag_PLOWABLE(), footwear_factor(), get_map(), get_thirst(), Creature::has_flag(), has_trait(), mod_healthy_mod(), mod_thirst(), one_in(), pos(), trait_ROOTS2, trait_ROOTS3, turgid, vitamin_mod(), and x_in_y().

Referenced by player_activity::do_turn().

◆ rooted_message()

void Character::rooted_message ( ) const

Handles rooting effects.

Definition at line 8788 of file character.cpp.

8789{
8790 bool wearing_shoes = is_wearing_shoes( side::LEFT ) || is_wearing_shoes( side::RIGHT );
8791 if( ( has_trait( trait_ROOTS2 ) || has_trait( trait_ROOTS3 ) ) &&
8793 !wearing_shoes ) {
8794 add_msg( m_info, _( "You sink your roots into the soil." ) );
8795 }
8796}

References _, add_msg(), flag_PLOWABLE(), get_map(), Creature::has_flag(), has_trait(), is_wearing_shoes(), LEFT, m_info, pos(), RIGHT, trait_ROOTS2, and trait_ROOTS3.

Referenced by player_activity::start_or_resume().

◆ run_cost()

int Character::run_cost ( int  base_cost,
bool  diag = false 
) const

Returns the player's modified base movement cost.

Definition at line 9976 of file character.cpp.

9977{
9978 float movecost = static_cast<float>( base_cost );
9979 if( diag ) {
9980 movecost *= 0.7071f; // because everything here assumes 100 is base
9981 }
9982 const bool flatground = movecost < 105;
9983 map &here = get_map();
9984 // The "FLAT" tag includes soft surfaces, so not a good fit.
9985 const bool on_road = flatground && here.has_flag( "ROAD", pos() );
9986 const bool on_fungus = here.has_flag_ter_or_furn( "FUNGUS", pos() );
9987
9988 if( !is_mounted() ) {
9989 if( movecost > 100 ) {
9990 movecost *= mutation_value( "movecost_obstacle_modifier" );
9991 if( movecost < 100 ) {
9992 movecost = 100;
9993 }
9994 }
9995 if( has_trait( trait_M_IMMUNE ) && on_fungus ) {
9996 if( movecost > 75 ) {
9997 // Mycal characters are faster on their home territory, even through things like shrubs
9998 movecost = 75;
9999 }
10000 }
10001
10002 // Linearly increase move cost relative to individual leg hp.
10003 movecost += 50 * ( 1 - static_cast<float>( get_part_hp_cur( bodypart_id( "leg_l" ) ) ) /
10004 static_cast<float>( get_part_hp_max( bodypart_id( "leg_l" ) ) ) );
10005 movecost += 50 * ( 1 - static_cast<float>( get_part_hp_cur( bodypart_id( "leg_r" ) ) ) /
10006 static_cast<float>( get_part_hp_max( bodypart_id( "leg_r" ) ) ) );
10007 movecost *= mutation_value( "movecost_modifier" );
10008 if( flatground ) {
10009 movecost *= mutation_value( "movecost_flatground_modifier" );
10010 }
10012 movecost *= .9f;
10013 }
10015 if( move_mode == CMM_RUN ) {
10016 movecost *= 0.85f;
10017 } else {
10018 movecost *= 0.95f;
10019 }
10020 } else if( has_bionic( bio_jointservo ) ) {
10021 movecost *= 1.1f;
10022 }
10023
10024 if( worn_with_flag( "SLOWS_MOVEMENT" ) ) {
10025 movecost *= 1.1f;
10026 }
10027 if( worn_with_flag( "FIN" ) ) {
10028 movecost *= 1.5f;
10029 }
10030 if( worn_with_flag( "ROLLER_INLINE" ) ) {
10031 if( on_road ) {
10032 movecost *= 0.5f;
10033 } else {
10034 movecost *= 1.5f;
10035 }
10036 }
10037 // Quad skates might be more stable than inlines,
10038 // but that also translates into a slower speed when on good surfaces.
10039 if( worn_with_flag( "ROLLER_QUAD" ) ) {
10040 if( on_road ) {
10041 movecost *= 0.7f;
10042 } else {
10043 movecost *= 1.3f;
10044 }
10045 }
10046 // Skates with only one wheel (roller shoes) are fairly less stable
10047 // and fairly slower as well
10048 if( worn_with_flag( "ROLLER_ONE" ) ) {
10049 if( on_road ) {
10050 movecost *= 0.85f;
10051 } else {
10052 movecost *= 1.1f;
10053 }
10054 }
10055
10056 movecost +=
10057 ( ( encumb( bp_foot_l ) + encumb( bp_foot_r ) ) * 2.5 +
10058 ( encumb( bp_leg_l ) + encumb( bp_leg_r ) ) * 1.5 ) / 10;
10059
10060 // ROOTS3 does slow you down as your roots are probing around for nutrients,
10061 // whether you want them to or not. ROOTS1 is just too squiggly without shoes
10062 // to give you some stability. Plants are a bit of a slow-mover. Deal.
10063 if( has_trait( trait_ROOTS3 ) && here.has_flag( "DIGGABLE", pos() ) ) {
10064 movecost += 10 * footwear_factor();
10065 }
10066
10068 movecost /= stamina_move_cost_modifier();
10069
10070 if( movecost < 20.0 ) {
10071 movecost = 20.0;
10072 }
10073 }
10074
10075 if( diag ) {
10076 movecost *= M_SQRT2;
10077 }
10078
10079 return static_cast<int>( movecost );
10080}
static const trait_id trait_M_IMMUNE("M_IMMUNE")
static const trait_id trait_PADDED_FEET("PADDED_FEET")
static const bionic_id bio_jointservo("bio_jointservo")
#define M_SQRT2
Definition: math_defines.h:29

References bio_jointservo, bonus_from_enchantments(), bp_foot_l, bp_foot_r, bp_leg_l, bp_leg_r, CMM_RUN, encumb(), footwear_factor(), get_map(), Creature::get_part_hp_cur(), Creature::get_part_hp_max(), has_active_bionic(), has_bionic(), map::has_flag(), map::has_flag_ter_or_furn(), has_trait(), is_mounted(), M_SQRT2, enchant_vals::MOVE_COST, move_mode, mutation_value(), pos(), stamina_move_cost_modifier(), trait_M_IMMUNE, trait_PADDED_FEET, trait_ROOTS3, and worn_with_flag().

Referenced by draw_speed_tab(), npc::move_to(), speed_description(), speed_rating(), npc::speed_rating(), and game::walk_move().

◆ rust_rate()

int Character::rust_rate ( ) const

Returns the player's skill rust rate.

Intelligence reduces skill rust by 10% per level above 8

Definition at line 3361 of file character.cpp.

3362{
3363 const std::string &rate_option = get_option<std::string>( "SKILL_RUST" );
3364 if( rate_option == "off" ) {
3365 return 0;
3366 }
3367
3368 // Stat window shows stat effects on based on current stat
3369 int intel = get_int();
3370 /** @EFFECT_INT reduces skill rust by 10% per level above 8 */
3371 int ret = ( ( rate_option == "vanilla" || rate_option == "capped" ) ?
3372 100 : 100 + 10 * ( intel - 8 ) );
3373
3374 ret *= mutation_value( "skill_rust_multiplier" );
3375
3376 if( ret < 0 ) {
3377 ret = 0;
3378 }
3379
3380 return ret;
3381}

References get_int(), mutation_value(), and cata::hash64_detail::ret.

Referenced by do_skill_rust(), draw_stats_info(), and set_stats().

◆ scored_crit()

bool Character::scored_crit ( float  target_dodge,
const item weap 
) const

Returns true if the player scores a critical hit.

Definition at line 726 of file melee.cpp.

727{
728 return rng_float( 0, 1.0 ) < crit_chance( hit_roll(), target_dodge, weap );
729}
double crit_chance(float roll_hit, float target_dodge, const item &weap) const
Returns the chance to critical given a hit roll and target's dodge roll.
Definition: melee.cpp:739

References crit_chance(), hit_roll(), and rng_float().

Referenced by melee_attack().

◆ sees() [1/2]

bool Character::sees ( const Creature critter) const
overridevirtual

The functions check whether this creature can see the target.

The target may either be another creature (critter), or a specific point on the map.

The function that take another creature as input should check visibility of that creature (e.g. not digging, or otherwise invisible). They must than check whether the location of the other monster is visible.

Reimplemented from Creature.

Definition at line 10405 of file character.cpp.

10406{
10407 // This handles only the player/npc specific stuff (monsters don't have traits or bionics).
10408 const int dist = rl_dist( pos(), critter.pos() );
10409 if( dist <= 3 && has_active_mutation( trait_ANTENNAE ) ) {
10410 return true;
10411 }
10412
10413 return Creature::sees( critter );
10414}
virtual bool sees(const Creature &critter) const
The functions check whether this creature can see the target.
Definition: creature.cpp:203

References has_active_mutation(), Creature::pos(), pos(), rl_dist(), Creature::sees(), and trait_ANTENNAE.

◆ sees() [2/2]

bool Character::sees ( const tripoint t,
bool  is_player = false,
int  range_mod = 0 
) const
overridevirtual

Reimplemented from Creature.

Definition at line 10388 of file character.cpp.

10389{
10390 const int wanted_range = rl_dist( pos(), t );
10391 bool can_see = is_player() ? get_map().pl_sees( t, wanted_range ) :
10392 Creature::sees( t );
10393 // Clairvoyance is now pretty cheap, so we can check it early
10394 if( wanted_range < MAX_CLAIRVOYANCE && wanted_range < clairvoyance() ) {
10395 return true;
10396 }
10397
10398 if( can_see && wanted_range > unimpaired_range() ) {
10399 can_see = false;
10400 }
10401
10402 return can_see;
10403}
int unimpaired_range() const
Returns the player maximum vision range factoring in mutations, diseases, and other effects.
Definition: character.cpp:616
int clairvoyance() const
Returns the distance the player can see through walls.
Definition: character.cpp:675
bool pl_sees(const tripoint &t, int max_range) const
Whether the player character (g->u) can see the given square (local map coordinates).
Definition: lightmap.cpp:777

References clairvoyance(), get_map(), Creature::is_player(), MAX_CLAIRVOYANCE, map::pl_sees(), pos(), rl_dist(), Creature::sees(), and unimpaired_range().

Referenced by npc::address_needs(), npc::address_player(), grid_furn_transform_queue::apply(), npc::assess_danger(), bionics_uninstall_failure(), calculate_aim_cap(), game::catch_a_monster(), game::chat(), check_mount_is_spooked(), check_mount_will_move(), npc::check_or_use_weapon_cbm(), npc::complain(), npc::do_reload(), draw_critter_internal(), game::draw_line(), game::draw_look_around_cursor(), draw_throw_aim(), npc::drop_items(), explosion_handler::emp_blast(), npc::enough_time_to_reload(), npc::execute_action(), game::extended_description(), npc::find_corpse_to_pulp(), npc::find_item(), game::find_nearby_items(), heal_actor::finish_using(), game::fling_creature(), npc::follow_distance(), game::forced_door_closing(), fungal_effects::fungalize(), generic_multi_activity_check_requirement(), get_hostile_creatures(), get_path_avoid(), game::get_player_input(), get_visible_creatures(), game::handle_action(), npc::handle_sound(), vehicle::handle_trap(), npc::heal_player(), npc::heal_self(), talk_function::hostile(), is_visible_in_range(), mdeath::jabberwock(), game::knockback(), target_ui::list_friendlies_in_lof(), game::list_items(), game::look_around(), npc::method_of_attack(), npc::move(), npc::mug_player(), iuse::note_bionics(), target_ui::panel_target_info(), npc::pick_up_item(), pl_sees(), npc::pretend_fire(), npc::pretend_heal(), game::print_creature_info(), npc::print_info(), sounds::process_sound_markers(), npc::reach_omt_destination(), npc::regen_ai_cache(), iuse::robotcontrol(), character_funcs::search_surroundings(), npc::see_item_say_smth(), activity_handlers::spellcasting_finish(), fungal_effects::spread_fungus_one_tile(), suffer_from_schizophrenia(), game::try_get_right_click_action(), character_funcs::try_uncanny_dodge(), game::update_stair_monsters(), editmap::update_view_with_help(), countdown_actor::use(), and npc::use_painkiller().

◆ sees_with_infrared()

bool Character::sees_with_infrared ( const Creature critter) const

Check whether the this player can see the other creature with infrared.

This implies this player can see infrared and the target is visible with infrared (is warm). And of course a line of sight exists.

Definition at line 10161 of file character.cpp.

10162{
10163 if( !vision_mode_cache[IR_VISION] || !critter.is_warm() ) {
10164 return false;
10165 }
10166
10167 map &here = get_map();
10168 if( is_player() || critter.is_player() ) {
10169 // Players should not use map::sees
10170 // Likewise, players should not be "looked at" with map::sees, not to break symmetry
10171 return here.pl_line_of_sight( critter.pos(),
10173 }
10174
10175 return here.sees( pos(), critter.pos(), sight_range( current_daylight_level( calendar::turn ) ) );
10176}
double current_daylight_level(const time_point &p)
Returns the current seasonally-adjusted maximum daylight level.
Definition: calendar.cpp:171
bool sees(const tripoint &F, const tripoint &T, int range) const
Returns whether F sees T with a view range of range.
Definition: map.cpp:6145
bool pl_line_of_sight(const tripoint &t, int max_range) const
Uses the map cache to tell if the player could see the given square.
Definition: lightmap.cpp:795

References current_daylight_level(), get_map(), IR_VISION, Creature::is_player(), Creature::is_warm(), map::pl_line_of_sight(), Creature::pos(), pos(), map::sees(), sight_range(), calendar::turn, and vision_mode_cache.

Referenced by calculate_aim_cap(), draw_critter_internal(), target_ui::panel_target_info(), pl_sees(), and game::print_all_tile_info().

◆ sees_with_specials()

bool Character::sees_with_specials ( const Creature critter) const

Definition at line 6320 of file character.cpp.

6321{
6322 // electroreceptors grants vision of robots and electric monsters through walls
6324 ( critter.in_species( ROBOT ) || critter.has_flag( MF_ELECTRIC ) ) ) {
6325 return true;
6326 }
6327
6328 if( critter.digging() && has_active_bionic( bio_ground_sonar ) ) {
6329 // Bypass the check below, the bionic sonar also bypasses the sees(point) check because
6330 // walls don't block sonar which is transmitted in the ground, not the air.
6331 // TODO: this might need checks whether the player is in the air, or otherwise not connected
6332 // to the ground. It also might need a range check.
6333 return true;
6334 }
6335
6336 return false;
6337}
static const trait_id trait_ELECTRORECEPTORS("ELECTRORECEPTORS")
static const species_id ROBOT("ROBOT")
static const bionic_id bio_ground_sonar("bio_ground_sonar")
virtual bool digging() const
Definition: creature.cpp:180
@ MF_ELECTRIC
Definition: mtype.h:95

References bio_ground_sonar, Creature::digging(), has_active_bionic(), Creature::has_flag(), has_trait(), Creature::in_species(), MF_ELECTRIC, ROBOT, and trait_ELECTRORECEPTORS.

Referenced by draw_critter_internal(), target_ui::panel_target_info(), pl_sees(), and game::print_all_tile_info().

◆ set_base_age()

void Character::set_base_age ( int  age)

Definition at line 6745 of file character.cpp.

6746{
6747 init_age = age;
6748}

References age(), and init_age.

Referenced by debug_menu::character_edit_menu(), and set_description().

◆ set_base_height()

void Character::set_base_height ( int  height)

Definition at line 6774 of file character.cpp.

6775{
6777}

References height(), and init_height.

Referenced by debug_menu::character_edit_menu(), and set_description().

◆ set_check_encumbrance()

void Character::set_check_encumbrance ( bool  new_check)
inline

Definition at line 1989 of file character.h.

1989 {
1990 check_encumbrance = new_check;
1991 }

References check_encumbrance.

◆ set_destination()

void Character::set_destination ( const std::vector< tripoint > &  route,
const player_activity new_destination_activity = player_activity() 
)

◆ set_destination_activity()

void Character::set_destination_activity ( const player_activity new_destination_activity)

Definition at line 939 of file character.cpp.

940{
941 destination_activity = new_destination_activity;
942}

References destination_activity.

Referenced by set_destination().

◆ set_dex_bonus()

void Character::set_dex_bonus ( int  ndex)
virtual

Definition at line 4147 of file character.cpp.

4148{
4149 dex_bonus = ndex;
4150 dex_cur = std::max( 0, dex_max + dex_bonus );
4151}

References dex_bonus, dex_cur, and dex_max.

◆ set_fac_id()

void Character::set_fac_id ( const std::string &  my_fac_id)

Definition at line 7706 of file character.cpp.

7707{
7708 fac_id = faction_id( my_fac_id );
7709}
faction_id fac_id
Definition: character.h:2169
string_id< faction > faction_id
Definition: clzones.h:30

References fac_id.

Referenced by npc_template::load().

◆ set_fatigue()

void Character::set_fatigue ( int  nfatigue)
virtual

Definition at line 4428 of file character.cpp.

4429{
4430 nfatigue = std::max( nfatigue, 0 );
4431 if( fatigue != nfatigue ) {
4432 fatigue = nfatigue;
4433 on_stat_change( "fatigue", fatigue );
4434 }
4435}

References fatigue, and on_stat_change().

Referenced by npc::address_needs(), debug_menu::character_edit_menu(), check_needs_extremes(), environmental_revert_effect(), basecamp::finish_return(), hardcoded_effects(), mod_fatigue(), and update_needs().

◆ set_healthy()

void Character::set_healthy ( int  nhealthy)
virtual

Setters for health values exclusive to characters.

Definition at line 4230 of file character.cpp.

4231{
4232 healthy = nhealthy;
4233}

References healthy.

Referenced by debug_menu::character_edit_menu(), and environmental_revert_effect().

◆ set_healthy_mod()

void Character::set_healthy_mod ( int  nhealthy_mod)
virtual

Definition at line 4242 of file character.cpp.

4243{
4244 healthy_mod = nhealthy_mod;
4245}

References healthy_mod.

Referenced by debug_menu::character_edit_menu(), environmental_revert_effect(), suffer_from_radiation(), update_health(), and vomit().

◆ set_highest_cat_level()

void Character::set_highest_cat_level ( )

Recalculates mutation_category_level[] values for the player.

Definition at line 7750 of file character.cpp.

7751{
7753
7754 // For each of our mutations...
7755 for( const trait_id &mut : get_mutations() ) {
7756 // ...build up a map of all prerequisite/replacement mutations along the tree, along with their distance from the current mutation
7757 std::unordered_map<trait_id, int> dependency_map;
7758 build_mut_dependency_map( mut, dependency_map, 0 );
7759
7760 // Then use the map to set the category levels
7761 for( const std::pair<const trait_id, int> &i : dependency_map ) {
7762 const mutation_branch &mdata = i.first.obj();
7763 if( !mdata.flags.count( "NON_THRESH" ) ) {
7764 for( const std::string &cat : mdata.category ) {
7765 // Decay category strength based on how far it is from the current mutation
7766 mutation_category_level[cat] += 8 / static_cast<int>( std::pow( 2, i.second ) );
7767 }
7768 }
7769 }
7770 }
7771}

References build_mut_dependency_map(), mutation_branch::category, mutation_branch::flags, get_mutations(), and mutation_category_level.

Referenced by avatar::load(), mutate_towards(), remove_mutation(), and game::start_game().

◆ set_int_bonus()

void Character::set_int_bonus ( int  nint)
virtual

Definition at line 4157 of file character.cpp.

4158{
4159 int_bonus = nint;
4160 int_cur = std::max( 0, int_max + int_bonus );
4161}

References int_bonus, int_cur, and int_max.

◆ set_max_power_level()

void Character::set_max_power_level ( const units::energy npower_max)

Definition at line 1900 of file character.cpp.

1901{
1902 max_power_level = npower_max;
1903}

References max_power_level.

Referenced by bionics_install_failure(), and player::player().

◆ set_movement_mode()

virtual void Character::set_movement_mode ( character_movemode  mode)
pure virtual

Implemented in avatar, and npc.

Referenced by dismount().

◆ set_mutation()

◆ set_npc_ai_info_cache()

void Character::set_npc_ai_info_cache ( const std::string &  key,
double  val 
) const

Definition at line 10588 of file character.cpp.

10589{
10590 npc_ai_info_cache[key] = val;
10591}

References npc_ai_info_cache.

Referenced by npc::find_reloadable(), and npc_ai::weapon_value().

◆ set_pain()

void Character::set_pain ( int  npain)
overridevirtual

Sets new intensity of pain an reacts to it.

Reimplemented from Creature.

Definition at line 777 of file character.cpp.

778{
779 const int prev_pain = get_perceived_pain();
780 Creature::set_pain( npain );
781 const int cur_pain = get_perceived_pain();
782
783 if( cur_pain != prev_pain ) {
784 react_to_felt_pain( cur_pain - prev_pain );
785 on_stat_change( "perceived_pain", cur_pain );
786 }
787}
void react_to_felt_pain(int intensity)
Definition: character.cpp:726
virtual void set_pain(int npain)
Definition: creature.cpp:1363

References get_perceived_pain(), on_stat_change(), react_to_felt_pain(), and Creature::set_pain().

Referenced by environmental_revert_effect(), game::is_game_over(), and suffer_from_other_mutations().

◆ set_painkiller()

void Character::set_painkiller ( int  npkill)

Sets intensity of painkillers

Definition at line 9744 of file character.cpp.

9745{
9746 npkill = std::max( npkill, 0 );
9747 if( pkill != npkill ) {
9748 const int prev_pain = get_perceived_pain();
9749 pkill = npkill;
9750 on_stat_change( "pkill", pkill );
9751 const int cur_pain = get_perceived_pain();
9752
9753 if( cur_pain != prev_pain ) {
9754 react_to_felt_pain( cur_pain - prev_pain );
9755 on_stat_change( "perceived_pain", cur_pain );
9756 }
9757 }
9758}

References get_perceived_pain(), on_stat_change(), pkill, and react_to_felt_pain().

Referenced by activate_bionic(), environmental_revert_effect(), mod_painkiller(), iuse::smoking(), and iuse::weed_cake().

◆ set_per_bonus()

void Character::set_per_bonus ( int  nper)
virtual

Definition at line 4152 of file character.cpp.

4153{
4154 per_bonus = nper;
4155 per_cur = std::max( 0, per_max + per_bonus );
4156}

References per_bonus, per_cur, and per_max.

◆ set_power_level()

void Character::set_power_level ( const units::energy npower)

Definition at line 1895 of file character.cpp.

1896{
1897 power_level = std::min( npower, max_power_level );
1898}

References max_power_level, and power_level.

Referenced by activate_bionic(), avatar::create(), mod_power_level(), and player::player().

◆ set_rad()

void Character::set_rad ( int  new_rad)

◆ set_skill_level()

◆ set_sleep_deprivation()

void Character::set_sleep_deprivation ( int  nsleep_deprivation)
virtual

Definition at line 4437 of file character.cpp.

4438{
4439 sleep_deprivation = std::min( static_cast< int >( sleep_deprivation_levels::massive ), std::max( 0,
4440 nsleep_deprivation ) );
4441}

References massive, and sleep_deprivation.

Referenced by debug_menu::character_edit_menu(), environmental_revert_effect(), basecamp::finish_return(), mod_sleep_deprivation(), and update_needs().

◆ set_stamina()

◆ set_stashed_activity()

void Character::set_stashed_activity ( const player_activity act,
const player_activity act_back = player_activity() 
)

Definition at line 899 of file character.cpp.

900{
902 stashed_outbounds_backlog = act_back;
903}

References act, stashed_outbounds_activity, and stashed_outbounds_backlog.

◆ set_stim()

void Character::set_stim ( int  new_stim)

Definition at line 7020 of file character.cpp.

7021{
7022 stim = new_stim;
7023}

References stim.

Referenced by activate_bionic(), environmental_revert_effect(), modify_stimulation(), and update_needs().

◆ set_stored_kcal()

void Character::set_stored_kcal ( int  kcal)
virtual

Setters for need values exclusive to characters.

Definition at line 4298 of file character.cpp.

4299{
4300 if( stored_calories != kcal ) {
4301 stored_calories = std::min( kcal, max_stored_kcal() );
4302 }
4303}

References max_stored_kcal(), and stored_calories.

Referenced by debug_menu::character_edit_menu(), npc::consume_food(), avatar::create(), environmental_revert_effect(), marloss_common(), mod_stored_kcal(), and update_stomach().

◆ set_str_bonus()

void Character::set_str_bonus ( int  nstr)
virtual

Setters for stats exclusive to characters.

Definition at line 4142 of file character.cpp.

4143{
4144 str_bonus = nstr;
4145 str_cur = std::max( 0, str_max + str_bonus );
4146}

References str_bonus, str_cur, and str_max.

◆ set_thirst()

void Character::set_thirst ( int  nthirst)
virtual

Definition at line 4410 of file character.cpp.

4411{
4412 if( thirst != nthirst ) {
4413 thirst = nthirst;
4414 on_stat_change( "thirst", thirst );
4415 }
4416}

References on_stat_change(), and thirst.

Referenced by debug_menu::character_edit_menu(), npc::consume_food(), npc::consume_food_from_camp(), environmental_revert_effect(), basecamp::finish_return(), mod_thirst(), update_stomach(), and vomit().

◆ set_time_died()

void Character::set_time_died ( const time_point time)
inline

set the turn the turn the character died if not already done

Definition at line 1442 of file character.h.

1442 {
1444 time_died = time;
1445 }
1446 }
@ time
Recharges slowly with time.

References calendar::before_time_starts, time, and time_died.

Referenced by die().

◆ set_type_of_scent()

void Character::set_type_of_scent ( const scenttype_id id)

Definition at line 8710 of file character.cpp.

8711{
8712 type_of_scent = id;
8713}

References id, and type_of_scent.

Referenced by restore_scent(), update_type_of_scent(), and change_scent_iuse::use().

◆ set_underwater()

void Character::set_underwater ( bool  x)
overridevirtual

Reimplemented from Creature.

Definition at line 10575 of file character.cpp.

10576{
10577 if( is_underwater() != x ) {
10580 }
10581}
virtual void set_underwater(bool x)
Definition: creature.cpp:175

References Creature::is_underwater(), recalc_sight_limits(), and Creature::set_underwater().

Referenced by avatar_action::swim(), game::vertical_move(), and game::walk_move().

◆ setID()

void Character::setID ( character_id  i,
bool  force = false 
)

Definition at line 472 of file character.cpp.

473{
474 if( id.is_valid() && !force ) {
475 debugmsg( "tried to set id of a npc/player, but has already a id: %d", id.get_value() );
476 } else if( !i.is_valid() && !force ) {
477 debugmsg( "tried to set invalid id of a npc/player: %d", i.get_value() );
478 } else {
479 id = i;
480 }
481}
bool is_valid() const
Definition: character_id.h:19
int get_value() const
Definition: character_id.h:23

References debugmsg, character_id::get_value(), Creature::get_value(), and character_id::is_valid().

Referenced by player::load(), game::load(), npc::randomize(), and game::start_game().

◆ setpos()

◆ setx()

void Character::setx ( int  x)
inline

◆ sety()

void Character::sety ( int  y)
inline

◆ setz()

void Character::setz ( int  z)
inline

Definition at line 801 of file character.h.

801 {
802 setpos( tripoint( position.xy(), z ) );
803 }

References position, setpos(), and tripoint::xy().

Referenced by start_location::place_player(), and game::vertical_shift().

◆ shift_destination()

void Character::shift_destination ( const point shift)

Definition at line 10314 of file character.cpp.

10315{
10317 *next_expected_position += shift;
10318 }
10319
10320 for( auto &elem : auto_move_route ) {
10321 elem += shift;
10322 }
10323}

References auto_move_route, and next_expected_position.

Referenced by game::update_map().

◆ shoe_type_count()

int Character::shoe_type_count ( const itype_id it) const

Returns 1 if the player is wearing an item of that count on one foot, 2 if on both, and zero if on neither.

Definition at line 8903 of file character.cpp.

8904{
8905 int ret = 0;
8906 if( is_wearing_on_bp( it, bodypart_id( "foot_l" ) ) ) {
8907 ret++;
8908 }
8909 if( is_wearing_on_bp( it, bodypart_id( "foot_r" ) ) ) {
8910 ret++;
8911 }
8912 return ret;
8913}
bool is_wearing_on_bp(const itype_id &it, const bodypart_id &bp) const
Returns true if the player is wearing the item on the given body part.
Definition: character.cpp:3221

References is_wearing_on_bp(), and cata::hash64_detail::ret.

Referenced by avatar_action::swim(), and game::vertical_move().

◆ short_description()

std::string Character::short_description ( ) const

Definition at line 10303 of file character.cpp.

10304{
10305 return join( short_description_parts(), "; " );
10306}
std::vector< std::string > short_description_parts() const
arg_join< It, Sentinel, char > join(It begin, Sentinel end, string_view sep)
Returns an object that formats the iterator range [begin, end) with elements separated by sep.

References join(), and short_description_parts().

◆ short_description_parts()

std::vector< std::string > Character::short_description_parts ( ) const

Definition at line 10279 of file character.cpp.

10280{
10281 std::vector<std::string> result;
10282
10283 std::string gender = male ? _( "male" ) : _( "female" );
10284 result.push_back( name + ", " + gender );
10285 if( is_armed() ) {
10286 result.push_back( _( "Wielding: " ) + weapon.tname() );
10287 }
10288 const std::string worn_str = enumerate_as_string( worn.begin(), worn.end(),
10289 []( const item & it ) {
10290 return it.tname();
10291 } );
10292 if( !worn_str.empty() ) {
10293 result.push_back( _( "Wearing: " ) + worn_str );
10294 }
10295 const int visibility_cap = 0; // no cap
10296 const auto trait_str = visible_mutations( visibility_cap );
10297 if( !trait_str.empty() ) {
10298 result.push_back( _( "Traits: " ) + trait_str );
10299 }
10300 return result;
10301}
std::string visible_mutations(int visibility_cap) const
Returns an enumeration of visible mutations with colors.
Definition: mutation.cpp:1743

References _, enumerate_as_string(), is_armed(), male, name, item::tname(), visible_mutations(), weapon, and worn.

Referenced by short_description().

◆ shout()

void Character::shout ( std::string  msg = "",
bool  order = false 
)

Definition at line 7589 of file character.cpp.

7590{
7591 int base = 10;
7592 std::string shout;
7593
7594 // You can't shout without your face
7595 if( has_trait( trait_PROF_FOODP ) && !( is_wearing( itype_id( "foodperson_mask" ) ) ||
7596 is_wearing( itype_id( "foodperson_mask_on" ) ) ) ) {
7597 add_msg_if_player( m_warning, _( "You try to shout but you have no face!" ) );
7598 return;
7599 }
7600
7601 // Mutations make shouting louder, they also define the default message
7602 if( has_trait( trait_SHOUT3 ) ) {
7603 base = 20;
7604 if( msg.empty() ) {
7605 msg = is_player() ? _( "yourself let out a piercing howl!" ) : _( "a piercing howl!" );
7606 shout = "howl";
7607 }
7608 } else if( has_trait( trait_SHOUT2 ) ) {
7609 base = 15;
7610 if( msg.empty() ) {
7611 msg = is_player() ? _( "yourself scream loudly!" ) : _( "a loud scream!" );
7612 shout = "scream";
7613 }
7614 }
7615
7616 if( msg.empty() ) {
7617 msg = is_player() ? _( "yourself shout loudly!" ) : _( "a loud shout!" );
7618 shout = "default";
7619 }
7620 int noise = get_shout_volume();
7621
7622 // Minimum noise volume possible after all reductions.
7623 // Volume 1 can't be heard even by player
7624 constexpr int minimum_noise = 2;
7625
7626 if( noise <= base ) {
7627 std::string dampened_shout;
7628 std::transform( msg.begin(), msg.end(), std::back_inserter( dampened_shout ), tolower );
7629 msg = std::move( dampened_shout );
7630 }
7631
7632 // Screaming underwater is not good for oxygen and harder to do overall
7633 if( is_underwater() ) {
7635 mod_stat( "oxygen", -noise );
7636 }
7637 }
7638
7639 const int penalty = encumb( bp_mouth ) * 3 / 2;
7640 // TODO: indistinct noise descriptions should be handled in the sounds code
7641 if( noise <= minimum_noise ) {
7643 _( "The sound of your voice is almost completely muffled!" ) );
7644 msg = is_player() ? _( "your muffled shout" ) : _( "an indistinct voice" );
7645 } else if( noise * 2 <= noise + penalty ) {
7646 // The shout's volume is 1/2 or lower of what it would be without the penalty
7647 add_msg_if_player( m_warning, _( "The sound of your voice is significantly muffled!" ) );
7648 }
7649
7651 "shout", shout );
7652}
static const trait_id trait_GILLS_CEPH("GILLS_CEPH")
static const trait_id trait_GILLS("GILLS")
void shout(std::string msg="", bool order=false)
Definition: character.cpp:7589
int get_shout_volume() const
Definition: character.cpp:7546
bool move(avatar &you, map &m, const tripoint &d)
void transform(player &p, const tripoint &pos)
Transform the examined object into the object specified by its transforms_into property.
Definition: iexamine.cpp:1639

References _, Creature::add_msg_if_player(), sounds::alert, bp_mouth, encumb(), get_shout_volume(), has_trait(), Creature::is_player(), Creature::is_underwater(), is_wearing(), itype_id, m_warning, mod_stat(), avatar_action::move(), noise, sounds::order, pos(), shout(), sounds::sound(), trait_GILLS, trait_GILLS_CEPH, trait_PROF_FOODP, trait_SHOUT2, trait_SHOUT3, and iexamine::transform().

Referenced by game::chat(), dialogue::dynamic_line(), shout(), suffer_from_schizophrenia(), and suffer_while_awake().

◆ sight_impaired()

◆ sight_range()

int Character::sight_range ( int  light_level) const
overridevirtual

Returns the player's sight range.

Implements Creature.

Definition at line 592 of file character.cpp.

593{
594 if( light_level == 0 ) {
595 return 1;
596 }
597 /* Via Beer-Lambert we have:
598 * light_level * (1 / exp( LIGHT_TRANSPARENCY_OPEN_AIR * distance) ) <= LIGHT_AMBIENT_LOW
599 * Solving for distance:
600 * 1 / exp( LIGHT_TRANSPARENCY_OPEN_AIR * distance ) <= LIGHT_AMBIENT_LOW / light_level
601 * 1 <= exp( LIGHT_TRANSPARENCY_OPEN_AIR * distance ) * LIGHT_AMBIENT_LOW / light_level
602 * light_level <= exp( LIGHT_TRANSPARENCY_OPEN_AIR * distance ) * LIGHT_AMBIENT_LOW
603 * log(light_level) <= LIGHT_TRANSPARENCY_OPEN_AIR * distance + log(LIGHT_AMBIENT_LOW)
604 * log(light_level) - log(LIGHT_AMBIENT_LOW) <= LIGHT_TRANSPARENCY_OPEN_AIR * distance
605 * log(LIGHT_AMBIENT_LOW / light_level) <= LIGHT_TRANSPARENCY_OPEN_AIR * distance
606 * log(LIGHT_AMBIENT_LOW / light_level) * (1 / LIGHT_TRANSPARENCY_OPEN_AIR) <= distance
607 */
608 int range = static_cast<int>( -std::log( get_vision_threshold( static_cast<int>
609 ( get_map().ambient_light_at( pos() ) ) ) / static_cast<float>( light_level ) ) *
610 ( 1.0 / LIGHT_TRANSPARENCY_OPEN_AIR ) );
611
612 // Clamp to [1, sight_max].
613 return clamp( range, 1, sight_max );
614}
float get_vision_threshold(float light_level) const
Returns the apparent light level at which the player can see.
Definition: character.cpp:1716
static constexpr float LIGHT_TRANSPARENCY_OPEN_AIR
Definition: lightmap.h:36

References clamp(), get_map(), get_vision_threshold(), LIGHT_TRANSPARENCY_OPEN_AIR, pos(), and sight_max.

Referenced by game::calc_driving_offset(), overmap_sight_range(), sees_with_infrared(), and editmap::update_view_with_help().

◆ skin_name()

std::string Character::skin_name ( ) const
overridevirtual

Returns the name of the player's outer layer, e.g.

"armor plates"

Implements Creature.

Definition at line 581 of file character.cpp.

582{
583 // TODO: Return actual deflecting layer name
584 return _( "armor" );
585}

References _.

◆ sound_hallu()

void Character::sound_hallu ( )

Creates an auditory hallucination.

Definition at line 1710 of file suffer.cpp.

1711{
1712 // Random 'dangerous' sound from a random direction
1713 // 1/5 chance to be a loud sound
1714 std::vector<std::string> dir{ "north",
1715 "northeast",
1716 "northwest",
1717 "south",
1718 "southeast",
1719 "southwest",
1720 "east",
1721 "west" };
1722
1723 std::vector<std::string> dirz{ "and above you ", "and below you " };
1724
1725 std::vector<std::tuple<std::string, std::string, std::string>> desc{
1726 std::make_tuple( "whump!", "smash_fail", "t_door_c" ),
1727 std::make_tuple( "crash!", "smash_success", "t_door_c" ),
1728 std::make_tuple( "glass breaking!", "smash_success", "t_window_domestic" ) };
1729
1730 std::vector<std::tuple<std::string, std::string, std::string>> desc_big{
1731 std::make_tuple( "huge explosion!", "explosion", "default" ),
1732 std::make_tuple( "bang!", "fire_gun", "glock_19" ),
1733 std::make_tuple( "blam!", "fire_gun", "mossberg_500" ),
1734 std::make_tuple( "crash!", "smash_success", "t_wall" ),
1735 std::make_tuple( "SMASH!", "smash_success", "t_wall" ) };
1736
1737 std::string i_dir = dir[rng( 0, dir.size() - 1 )];
1738
1739 if( one_in( 10 ) ) {
1740 i_dir += " " + dirz[rng( 0, dirz.size() - 1 )];
1741 }
1742
1743 std::string i_desc;
1744 std::pair<std::string, std::string> i_sound;
1745 if( one_in( 5 ) ) {
1746 int r_int = rng( 0, desc_big.size() - 1 );
1747 i_desc = std::get<0>( desc_big[r_int] );
1748 i_sound = std::make_pair( std::get<1>( desc_big[r_int] ), std::get<2>( desc_big[r_int] ) );
1749 } else {
1750 int r_int = rng( 0, desc.size() - 1 );
1751 i_desc = std::get<0>( desc[r_int] );
1752 i_sound = std::make_pair( std::get<1>( desc[r_int] ), std::get<2>( desc[r_int] ) );
1753 }
1754
1755 add_msg( m_warning, _( "From the %1$s you hear %2$s" ), i_dir, i_desc );
1756 sfx::play_variant_sound( i_sound.first, i_sound.second, rng( 20, 80 ) );
1757}
void play_variant_sound(const std::string &id, const std::string &variant, int volume, units::angle angle, double pitch_min=-1.0, double pitch_max=-1.0)
Definition: sounds.cpp:1597

References _, add_msg(), m_warning, one_in(), sfx::play_variant_sound(), and rng().

Referenced by hardcoded_effects(), and suffer_from_schizophrenia().

◆ speed_rating()

float Character::speed_rating ( ) const
overridevirtual

Returns an approximate number of tiles this creature can travel per turn.

Implements Creature.

Reimplemented in npc.

Definition at line 9951 of file character.cpp.

9952{
9953 float ret = get_speed() / 100.0f;
9954 ret *= 100.0f / run_cost( 100, false );
9955 // Adjustment for player being able to run, but not doing so at the moment
9956 if( move_mode != CMM_RUN ) {
9957 ret *= 1.0f + ( static_cast<float>( get_stamina() ) / static_cast<float>( get_stamina_max() ) );
9958 }
9959 return ret;
9960}
int run_cost(int base_cost, bool diag=false) const
Returns the player's modified base movement cost.
Definition: character.cpp:9976

References CMM_RUN, get_speed(), get_stamina(), get_stamina_max(), move_mode, cata::hash64_detail::ret, and run_cost().

◆ spores()

void Character::spores ( )

Definition at line 8732 of file character.cpp.

8733{
8734 map &here = get_map();
8735 fungal_effects fe( *g, here );
8736 //~spore-release sound
8737 sounds::sound( pos(), 10, sounds::sound_t::combat, _( "Pouf!" ), false, "misc", "puff" );
8738 for( const tripoint &sporep : here.points_in_radius( pos(), 1 ) ) {
8739 if( sporep == pos() ) {
8740 continue;
8741 }
8742 fe.fungalize( sporep, this, 0.25 );
8743 }
8744}

References _, sounds::combat, fungal_effects::fungalize(), g, get_map(), map::points_in_radius(), pos(), and sounds::sound().

Referenced by activate_mutation(), hardcoded_effects(), and suffer_while_awake().

◆ stability_roll()

float Character::stability_roll ( ) const
overridevirtual

Returns value of player's stable footing.

Strength improves player stability roll Perception slightly improves player stability roll Dexterity slightly improves player stability roll Melee improves player stability roll

Implements Creature.

Definition at line 10603 of file character.cpp.

10604{
10605 /** @EFFECT_STR improves player stability roll */
10606
10607 /** @EFFECT_PER slightly improves player stability roll */
10608
10609 /** @EFFECT_DEX slightly improves player stability roll */
10610
10611 /** @EFFECT_MELEE improves player stability roll */
10612 return get_melee() + get_str() + ( get_per() / 3.0f ) + ( get_dex() / 4.0f );
10613}
float get_melee() const override
Returns melee skill level, to be used to throttle dodge practice.
Definition: melee.cpp:857

References get_dex(), get_melee(), get_per(), and get_str().

Referenced by on_hit().

◆ stamina_move_cost_modifier()

float Character::stamina_move_cost_modifier ( ) const

Definition at line 7113 of file character.cpp.

7114{
7115 // Both walk and run speed drop to half their maximums as stamina approaches 0.
7116 // Convert stamina to a float first to allow for decimal place carrying
7117 float stamina_modifier = ( static_cast<float>( get_stamina() ) / get_stamina_max() + 1 ) / 2;
7118 if( move_mode == CMM_RUN && get_stamina() >= 0 ) {
7119 // Rationale: Average running speed is 2x walking speed. (NOT sprinting)
7120 stamina_modifier *= 2.0;
7121 }
7122 if( move_mode == CMM_CROUCH ) {
7123 stamina_modifier *= 0.5;
7124 }
7125 return stamina_modifier;
7126}

References CMM_CROUCH, CMM_RUN, get_stamina(), get_stamina_max(), and move_mode.

Referenced by burn_move_stamina(), and run_cost().

◆ start_destination_activity()

void Character::start_destination_activity ( )

Definition at line 10477 of file character.cpp.

10478{
10479 if( !has_destination_activity() ) {
10480 debugmsg( "Tried to start invalid destination activity" );
10481 return;
10482 }
10483
10486}
void clear_destination()
bool has_destination_activity() const

References assign_activity(), clear_destination(), debugmsg, get_destination_activity(), and has_destination_activity().

Referenced by game::handle_action(), and npc::move().

◆ start_hauling()

void Character::start_hauling ( )

Definition at line 9122 of file character.cpp.

9123{
9124 add_msg( _( "You start hauling items along the ground." ) );
9125 if( is_armed() ) {
9126 add_msg( m_warning, _( "Your hands are not free, which makes hauling slower." ) );
9127 }
9128 hauling = true;
9129}

References _, add_msg(), hauling, is_armed(), and m_warning.

Referenced by haul().

◆ stop_hauling()

void Character::stop_hauling ( )

Definition at line 9131 of file character.cpp.

9132{
9133 add_msg( _( "You stop hauling items." ) );
9134 hauling = false;
9135 if( has_activity( ACT_MOVE_ITEMS ) ) {
9137 }
9138}

References _, ACT_MOVE_ITEMS, add_msg(), cancel_activity(), has_activity(), and hauling.

Referenced by cancel_activity(), haul(), game::place_player(), avatar::set_movement_mode(), and game::vertical_move().

◆ store()

void Character::store ( JsonOut json) const
protected

Load variables from json into object.

These variables are common to both the avatar and NPCs.

Definition at line 646 of file savegame_json.cpp.

647{
648 Creature::store( json );
649
650 // assumes already in Character object
651 // positional data
652 json.member( "posx", position.x );
653 json.member( "posy", position.y );
654 json.member( "posz", position.z );
655
656 // stat
657 json.member( "str_cur", str_cur );
658 json.member( "str_max", str_max );
659 json.member( "dex_cur", dex_cur );
660 json.member( "dex_max", dex_max );
661 json.member( "int_cur", int_cur );
662 json.member( "int_max", int_max );
663 json.member( "per_cur", per_cur );
664 json.member( "per_max", per_max );
665
666 json.member( "str_bonus", str_bonus );
667 json.member( "dex_bonus", dex_bonus );
668 json.member( "per_bonus", per_bonus );
669 json.member( "int_bonus", int_bonus );
670
671 json.member( "base_age", init_age );
672 json.member( "base_height", init_height );
673
674 if( prof.is_valid() ) {
675 json.member( "profession", prof );
676 }
677 json.member( "custom_profession", custom_profession );
678
679 // health
680 json.member( "healthy", healthy );
681 json.member( "healthy_mod", healthy_mod );
682 json.member( "healed_24h", healed_total );
683
684 // status
685 json.member( "temp_cur", temp_cur );
686 json.member( "temp_conv", temp_conv );
687 json.member( "frostbite_timer", frostbite_timer );
688 json.member( "body_wetness", body_wetness );
689
690 // needs
691 json.member( "thirst", thirst );
692 json.member( "fatigue", fatigue );
693 json.member( "sleep_deprivation", sleep_deprivation );
694 json.member( "stored_calories", stored_calories );
695 json.member( "radiation", radiation );
696 json.member( "stamina", stamina );
697 json.member( "vitamin_levels", vitamin_levels );
698 json.member( "pkill", pkill );
699 json.member( "omt_path", omt_path );
700 json.member( "consumption_history", consumption_history );
701
702 // crafting etc
703 json.member( "destination_activity", destination_activity );
704 json.member( "activity", activity );
705 json.member( "stashed_outbounds_activity", stashed_outbounds_activity );
706 json.member( "stashed_outbounds_backlog", stashed_outbounds_backlog );
707 json.member( "backlog", backlog );
708 json.member( "activity_vehicle_part_index", activity_vehicle_part_index ); // NPC activity
709
710 // handling for storing activity requirements
711 if( !backlog.empty() && !backlog.front().str_values.empty() && ( ( activity &&
712 activity.id() == activity_id( "ACT_FETCH_REQUIRED" ) ) || ( destination_activity &&
713 destination_activity.id() == activity_id( "ACT_FETCH_REQUIRED" ) ) ) ) {
714 requirement_data things_to_fetch = requirement_id( backlog.front().str_values.back() ).obj();
715 json.member( "fetch_data", things_to_fetch );
716 }
717
718 json.member( "stim", stim );
719 json.member( "type_of_scent", type_of_scent );
720
721 // breathing
722 json.member( "oxygen", oxygen );
723
724 // traits: permanent 'mutations' more or less
725 json.member( "traits", my_traits );
726 json.member( "mutations", my_mutations );
727 json.member( "magic", magic );
728 json.member( "martial_arts_data", martial_arts_data );
729 // "Fracking Toasters" - Saul Tigh, toaster
730 json.member( "my_bionics", *my_bionics );
731
732 json.member_as_string( "move_mode", move_mode );
733
734 // storing the mount
735 if( is_mounted() ) {
736 json.member( "mounted_creature", g->critter_tracker->temporary_id( *mounted_creature ) );
737 }
738
739 morale->store( json );
740
741 // skills
742 json.member( "skills" );
743 json.start_object();
744 for( const auto &pair : *_skills ) {
745 json.member( pair.first.str(), pair.second );
746 }
747 json.end_object();
748
749 // npc: unimplemented, potentially useful
750 json.member( "learned_recipes", *learned_recipes );
751 autolearn_skills_stamp->clear(); // Invalidates the cache
752
753 // npc; unimplemented
754 if( power_level < 1_kJ ) {
755 json.member( "power_level", std::to_string( units::to_joule( power_level ) ) + " J" );
756 } else {
757 json.member( "power_level", units::to_kilojoule( power_level ) );
758 }
759 json.member( "max_power_level", units::to_kilojoule( max_power_level ) );
760
761 if( !overmap_time.empty() ) {
762 json.member( "overmap_time" );
763 json.start_array();
764 for( const std::pair<const point_abs_omt, time_duration> &pr : overmap_time ) {
765 json.write( pr.first );
766 json.write( pr.second );
767 }
768 json.end_array();
769 }
770 json.member( "stomach", stomach );
771 json.member( "automoveroute", auto_move_route );
772 json.member( "known_traps" );
773 json.start_array();
774 for( const auto &elem : known_traps ) {
775 json.start_object();
776 json.member( "x", elem.first.x );
777 json.member( "y", elem.first.y );
778 json.member( "z", elem.first.z );
779 json.member( "trap", elem.second );
780 json.end_object();
781 }
782 json.end_array();
783}
void store(JsonOut &jsout) const
These two functions are responsible for storing and loading the members of this class to/from json da...
void member_as_string(const std::string &name, const T &value)
Definition: json.h:747
void end_array()
Definition: json.cpp:2028
void start_array(bool wrap=false)
Definition: json.cpp:2017
void start_object(bool wrap=false)
Definition: json.cpp:1998
void write(T val)
Definition: json.h:616
void end_object()
Definition: json.cpp:2009
void member(const std::string &name)
Definition: json.cpp:2113

References _skills, activity, activity_vehicle_part_index, auto_move_route, autolearn_skills_stamp, backlog, body_wetness, consumption_history, custom_profession, destination_activity, dex_bonus, dex_cur, dex_max, JsonOut::end_array(), JsonOut::end_object(), fatigue, frostbite_timer, g, healed_total, healthy, healthy_mod, player_activity::id(), init_age, init_height, int_bonus, int_cur, int_max, is_mounted(), string_id< T >::is_valid(), known_traps, learned_recipes, magic, martial_arts_data, max_power_level, JsonOut::member(), JsonOut::member_as_string(), morale, mounted_creature, move_mode, my_bionics, my_mutations, my_traits, string_id< T >::obj(), omt_path, overmap_time, oxygen, per_bonus, per_cur, per_max, pkill, position, power_level, prof, radiation, sleep_deprivation, stamina, JsonOut::start_array(), JsonOut::start_object(), stashed_outbounds_activity, stashed_outbounds_backlog, stim, stomach, Creature::store(), stored_calories, str_bonus, str_cur, str_max, temp_conv, temp_cur, thirst, units::to_joule(), units::to_kilojoule(), to_string(), type_of_scent, vitamin_levels, JsonOut::write(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by player::store().

◆ suffer()

void Character::suffer ( )

Handles a large number of timers decrementing and other randomized effects.

Definition at line 1472 of file suffer.cpp.

1473{
1474 const int current_stim = get_stim();
1475 // TODO: Remove this section and encapsulate hp_cur
1476 for( const std::pair<const bodypart_str_id, bodypart> &elem : get_body() ) {
1477 if( elem.second.get_hp_cur() <= 0 ) {
1478 add_effect( effect_disabled, 1_turns, elem.first->token );
1479 }
1480 }
1481
1482 for( bionic &bio : *my_bionics ) {
1483 process_bionic( bio );
1484 }
1485
1486 for( std::pair<const trait_id, char_trait_data> &mut : my_mutations ) {
1487 const mutation_branch &mdata = mut.first.obj();
1488 if( calendar::once_every( 1_minutes ) ) {
1489 suffer_water_damage( mdata );
1490 }
1491 char_trait_data &tdata = mut.second;
1492 if( tdata.powered ) {
1493 suffer_mutation_power( mdata, tdata );
1494 }
1495 }
1496
1497 if( is_underwater() ) {
1499 }
1500
1502
1503 if( !in_sleep_state() ) {
1504 suffer_while_awake( current_stim );
1505 } // Done with while-awake-only effects
1506
1507 if( has_trait( trait_ASTHMA ) ) {
1508 suffer_from_asthma( current_stim );
1509 }
1510
1516 suffer_from_stimulants( current_stim );
1518 // Stimulants can lessen the PERCEIVED effects of sleep deprivation, but
1519 // they do nothing to cure it. As such, abuse is even more dangerous now.
1520 if( current_stim > 0 ) {
1521 // 100% of blacking out = 20160sd ; Max. stim modifier = 12500sd @ 250stim
1522 // Note: Very high stim already has its own slew of bad effects,
1523 // so the "useful" part of this bonus is actually lower.
1524 sleep_deprivation -= current_stim * 50;
1525 }
1526
1528 //Suffer from enchantments
1529 enchantment_cache->activate_passive( *this );
1530
1531 if( calendar::once_every( 1_hours ) ) {
1533 }
1534}
void suffer_in_sunlight()
Definition: suffer.cpp:718
void suffer_from_artifacts()
Definition: suffer.cpp:1321
void suffer_from_addictions()
Definition: suffer.cpp:273
void suffer_from_stimulants(int current_stim)
Definition: suffer.cpp:1343
void suffer_mutation_power(const mutation_branch &mdata, char_trait_data &tdata)
Definition: suffer.cpp:203
void suffer_water_damage(const mutation_branch &mdata)
suffer() subcalls
Definition: suffer.cpp:183
void suffer_while_awake(int current_stim)
Definition: suffer.cpp:300
void process_bionic(bionic &bio)
Handles bionic effects over time of the entered bionic.
Definition: bionics.cpp:1523
void suffer_from_other_mutations()
Definition: suffer.cpp:945
void suffer_without_sleep(int sleep_deprivation)
Definition: suffer.cpp:1385
void suffer_while_underwater()
Definition: suffer.cpp:250
void suffer_from_bad_bionics()
Definition: suffer.cpp:1228
void suffer_from_radiation()
Definition: suffer.cpp:1054
void suffer_from_asthma(int current_stim)
Definition: suffer.cpp:616
static const efftype_id effect_accumulated_mutagen("accumulated_mutagen")
static const efftype_id effect_disabled("disabled")
static const trait_id trait_ASTHMA("ASTHMA")

References Creature::add_effect(), effect_accumulated_mutagen, effect_disabled, enchantment_cache, Creature::get_body(), get_sleep_deprivation(), get_stim(), has_trait(), in_sleep_state(), Creature::is_underwater(), my_bionics, my_mutations, num_bp, calendar::once_every(), char_trait_data::powered, process_bionic(), sleep_deprivation, suffer_from_addictions(), suffer_from_artifacts(), suffer_from_asthma(), suffer_from_bad_bionics(), suffer_from_other_mutations(), suffer_from_radiation(), suffer_from_stimulants(), suffer_in_sunlight(), suffer_mutation_power(), suffer_water_damage(), suffer_while_awake(), suffer_while_underwater(), suffer_without_sleep(), and trait_ASTHMA.

Referenced by process_turn().

◆ suffer_from_addictions()

void Character::suffer_from_addictions ( )
private

Definition at line 273 of file suffer.cpp.

274{
275 time_duration timer = -6_hours;
276 if( has_trait( trait_ADDICTIVE ) ) {
277 timer = -10_hours;
278 } else if( has_trait( trait_NONADDICTIVE ) ) {
279 timer = -3_hours;
280 }
281 for( addiction &cur_addiction : addictions ) {
282 if( cur_addiction.sated <= 0_turns &&
283 cur_addiction.intensity >= MIN_ADDICTION_LEVEL ) {
284 addict_effect( *this, cur_addiction );
285 }
286 cur_addiction.sated -= 1_turns;
287 // Higher intensity addictions heal faster
288 if( cur_addiction.sated - 10_minutes * cur_addiction.intensity < timer ) {
289 if( cur_addiction.intensity <= 2 ) {
290 rem_addiction( cur_addiction.type );
291 break;
292 } else {
293 cur_addiction.intensity--;
294 cur_addiction.sated = 0_turns;
295 }
296 }
297 }
298}
void addict_effect(Character &u, addiction &add)
Definition: addiction.cpp:57
constexpr int MIN_ADDICTION_LEVEL
Definition: addiction.h:13
void rem_addiction(add_type type)
Removes an addition from the player.
Definition: suffer.cpp:1950

References addict_effect(), addictions, has_trait(), MIN_ADDICTION_LEVEL, rem_addiction(), trait_ADDICTIVE, and trait_NONADDICTIVE.

Referenced by suffer().

◆ suffer_from_artifacts()

void Character::suffer_from_artifacts ( )
private

Definition at line 1321 of file suffer.cpp.

1322{
1323 // Artifact effects
1325 add_effect( effect_attention, 3_turns );
1326 }
1327
1329 get_weather().weather_id->precip < precip_class::heavy ) {
1333 }
1334
1335 if( has_artifact_with( AEP_MUTAGENIC ) && one_turn_in( 48_hours ) ) {
1336 mutate();
1337 }
1338 if( has_artifact_with( AEP_FORCE_TELEPORT ) && one_turn_in( 1_hours ) ) {
1339 teleport::teleport( *this );
1340 }
1341}
const weather_type_id & get_bad_weather() const
weather_type_id weather_override
Definition: weather.h:199
@ AEP_MUTAGENIC
Definition: enums.h:130
@ AEP_FORCE_TELEPORT
Definition: enums.h:138
@ AEP_ATTENTION
Definition: enums.h:131
@ AEP_BAD_WEATHER
Definition: enums.h:140
const weather_generator & get_cur_weather_gen() const
Definition: weather.cpp:1049
void set_nextweather(time_point t)
Definition: weather.cpp:1101
static const efftype_id effect_attention("attention")

References Creature::add_effect(), AEP_ATTENTION, AEP_BAD_WEATHER, AEP_FORCE_TELEPORT, AEP_MUTAGENIC, effect_attention, weather_generator::get_bad_weather(), weather_manager::get_cur_weather_gen(), get_weather(), has_artifact_with(), heavy, mutate(), calendar::once_every(), one_turn_in(), weather_manager::set_nextweather(), teleport::teleport(), calendar::turn, and weather_manager::weather_override.

Referenced by suffer().

◆ suffer_from_asthma()

void Character::suffer_from_asthma ( int  current_stim)
private

Definition at line 616 of file suffer.cpp.

617{
621 return;
622 }
623 if( !one_in( ( to_turns<int>( 6_hours ) - current_stim * 300 ) *
624 ( has_effect( effect_sleep ) ? 10 : 1 ) ) ) {
625 return;
626 }
627 bool auto_use = has_charges( itype_inhaler, 1 ) || has_charges( itype_oxygen_tank, 1 ) ||
629 bool oxygenator = has_bionic( bio_gills ) && get_power_level() >= ( bio_gills->power_trigger / 8 );
630 if( is_underwater() ) {
631 oxygen = oxygen / 2;
632 auto_use = false;
633 }
634
635 add_msg_player_or_npc( m_bad, _( "You have an asthma attack!" ),
636 "<npcname> starts wheezing and coughing." );
637
639 inventory map_inv;
640 map_inv.form_from_map( g->u.pos(), 2, &g->u );
641 // check if an inhaler is somewhere near
642 bool nearby_use = auto_use || oxygenator || map_inv.has_charges( itype_inhaler, 1 ) ||
643 map_inv.has_charges( itype_oxygen_tank, 1 ) ||
644 map_inv.has_charges( itype_smoxygen_tank, 1 );
645 // check if character has an oxygenator first
646 if( oxygenator ) {
648 add_msg_if_player( m_info, _( "You use your Oxygenator to clear it up, "
649 "then go back to sleep." ) );
650 } else if( auto_use ) {
652 add_msg_if_player( m_info, _( "You use your inhaler and go back to sleep." ) );
653 } else if( use_charges_if_avail( itype_oxygen_tank, 1 ) ||
655 add_msg_if_player( m_info, _( "You take a deep breath from your oxygen tank "
656 "and go back to sleep." ) );
657 }
658 } else if( nearby_use ) {
659 // create new variable to resolve a reference issue
660 int amount = 1;
661 map &here = get_map();
662 if( !here.use_charges( g->u.pos(), 2, itype_inhaler, amount ).empty() ) {
663 add_msg_if_player( m_info, _( "You use your inhaler and go back to sleep." ) );
664 } else if( !here.use_charges( g->u.pos(), 2, itype_oxygen_tank, amount ).empty() ||
665 !here.use_charges( g->u.pos(), 2, itype_smoxygen_tank, amount ).empty() ) {
666 add_msg_if_player( m_info, _( "You take a deep breath from your oxygen tank "
667 "and go back to sleep." ) );
668 }
669 } else {
670 add_effect( effect_asthma, rng( 5_minutes, 20_minutes ) );
671 if( has_effect( effect_sleep ) ) {
672 wake_up();
673 } else {
674 if( !is_npc() ) {
675 g->cancel_activity_or_ignore_query( distraction_type::asthma,
676 _( "You can't focus while choking!" ) );
677 }
678 }
679 }
680 } else if( auto_use ) {
681 int charges = 0;
683 moves -= 40;
684 charges = charges_of( itype_inhaler );
685 if( charges == 0 ) {
686 add_msg_if_player( m_bad, _( "You use your last inhaler charge." ) );
687 } else {
688 add_msg_if_player( m_info, vgettext( "You use your inhaler, "
689 "only %d charge left.",
690 "You use your inhaler, "
691 "only %d charges left.", charges ),
692 charges );
693 }
694 } else if( use_charges_if_avail( itype_oxygen_tank, 1 ) ||
696 moves -= 500; // synched with use action
698 if( charges == 0 ) {
699 add_msg_if_player( m_bad, _( "You breathe in last bit of oxygen "
700 "from the tank." ) );
701 } else {
702 add_msg_if_player( m_info, vgettext( "You take a deep breath from your oxygen "
703 "tank, only %d charge left.",
704 "You take a deep breath from your oxygen "
705 "tank, only %d charges left.", charges ),
706 charges );
707 }
708 }
709 } else {
710 add_effect( effect_asthma, rng( 5_minutes, 20_minutes ) );
711 if( !is_npc() ) {
712 g->cancel_activity_or_ignore_query( distraction_type::asthma,
713 _( "You can't focus while choking!" ) );
714 }
715 }
716}
bool use_charges_if_avail(const itype_id &it, int quantity)
Definition: character.cpp:9605
bool has_charges(const itype_id &it, int quantity, const std::function< bool(const item &)> &filter=return_true< item >) const
Definition: inventory.cpp:893
std::list< item > use_charges(const tripoint &origin, int range, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter=return_true< item >, basecamp *bcp=nullptr)
Definition: map.cpp:4919
static const efftype_id effect_datura("datura")
static const efftype_id effect_narcosis("narcosis")
static const efftype_id effect_adrenaline("adrenaline")
static const efftype_id effect_asthma("asthma")
static const itype_id itype_oxygen_tank("oxygen_tank")
static const itype_id itype_inhaler("inhaler")
static const itype_id itype_smoxygen_tank("smoxygen_tank")
static const bionic_id bio_gills("bio_gills")
static const efftype_id effect_took_antiasthmatic("took_antiasthmatic")

References _, Creature::add_effect(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), asthma, bio_gills, visitable< Character >::charges_of(), effect_adrenaline, effect_asthma, effect_datura, effect_narcosis, effect_sleep, effect_took_antiasthmatic, inventory::form_from_map(), g, get_map(), get_power_level(), has_bionic(), has_charges(), inventory::has_charges(), Creature::has_effect(), in_sleep_state(), Creature::is_npc(), Creature::is_underwater(), itype_inhaler, itype_oxygen_tank, itype_smoxygen_tank, m_bad, m_info, mod_power_level(), Creature::moves, one_in(), oxygen, bionic_data::power_trigger, rng(), map::use_charges(), use_charges_if_avail(), vgettext(), and wake_up().

Referenced by suffer().

◆ suffer_from_bad_bionics()

void Character::suffer_from_bad_bionics ( )
private

Definition at line 1228 of file suffer.cpp.

1229{
1230 // Negative bionics effects
1232 one_turn_in( 2_hours ) &&
1234 add_msg_if_player( m_bad, _( "You suffer a painful electrical discharge!" ) );
1235 mod_pain( 1 );
1236 moves -= 150;
1238
1239 if( weapon.typeId() == itype_e_handcuffs && weapon.charges > 0 ) {
1240 weapon.charges -= rng( 1, 3 ) * 50;
1241 if( weapon.charges < 1 ) {
1242 weapon.charges = 1;
1243 }
1244
1245 add_msg_if_player( m_good, _( "The %s seems to be affected by the discharge." ),
1246 weapon.tname() );
1247 }
1248 sfx::play_variant_sound( "bionics", "elec_discharge", 100 );
1249 }
1250 if( has_bionic( bio_dis_acid ) && one_turn_in( 150_minutes ) ) {
1251 add_msg_if_player( m_bad, _( "You suffer a burning acidic discharge!" ) );
1252 hurtall( 1, nullptr );
1253 sfx::play_variant_sound( "bionics", "acid_discharge", 100 );
1254 sfx::do_player_death_hurt( g->u, false );
1255 }
1256 if( has_bionic( bio_drain ) && get_power_level() > 24_kJ && one_turn_in( 1_hours ) ) {
1257 add_msg_if_player( m_bad, _( "Your batteries discharge slightly." ) );
1258 mod_power_level( -25_kJ );
1259 sfx::play_variant_sound( "bionics", "elec_crackle_low", 100 );
1260 }
1261 if( has_bionic( bio_noise ) && one_turn_in( 50_minutes ) &&
1263 // TODO: NPCs with said bionic
1264 if( !is_deaf() ) {
1265 add_msg( m_bad, _( "A bionic emits a crackle of noise!" ) );
1266 sfx::play_variant_sound( "bionics", "elec_blast", 100 );
1267 } else {
1268 add_msg_if_player( m_bad, _( "You feel your faulty bionic shuddering." ) );
1269 sfx::play_variant_sound( "bionics", "elec_blast_muffled", 100 );
1270 }
1271 sounds::sound( pos(), 60, sounds::sound_t::movement, _( "Crackle!" ) ); //sfx above
1272 }
1274 get_power_level() >= get_max_power_level() * .75 ) {
1275 mod_str_bonus( -3 );
1276 }
1277 if( has_bionic( bio_trip ) && one_turn_in( 50_minutes ) &&
1280 add_msg_if_player( m_bad, _( "Your vision pixelates!" ) );
1281 add_effect( effect_visuals, 10_minutes );
1282 sfx::play_variant_sound( "bionics", "pixelated", 100 );
1283 }
1284 if( has_bionic( bio_spasm ) && one_turn_in( 5_hours ) && !has_effect( effect_downed ) &&
1287 _( "Your malfunctioning bionic causes you to spasm and fall to the floor!" ),
1288 _( "<npcname> spasms and falls to the floor!" ) );
1289 mod_pain( 1 );
1290 add_effect( effect_stunned, 1_turns );
1291 add_effect( effect_downed, 10_turns, num_bp, 0 );
1292 sfx::play_variant_sound( "bionics", "elec_crackle_high", 100 );
1293 }
1295 one_turn_in( 2_hours ) ) {
1296 add_msg_if_player( m_bad, _( "Your bionics short-circuit, causing you to tremble and shiver." ) );
1298 add_effect( effect_shakes, 5_minutes );
1299 sfx::play_variant_sound( "bionics", "elec_crackle_med", 100 );
1300 }
1301 if( has_bionic( bio_leaky ) && one_turn_in( 6_minutes ) ) {
1302 mod_healthy_mod( -1, -200 );
1303 }
1304 if( has_bionic( bio_sleepy ) && one_turn_in( 50_minutes ) && !in_sleep_state() ) {
1305 mod_fatigue( 1 );
1306 }
1307 if( has_bionic( bio_itchy ) && one_turn_in( 50_minutes ) && !has_effect( effect_formication ) &&
1309 add_msg_if_player( m_bad, _( "Your malfunctioning bionic itches!" ) );
1310 body_part bp = random_body_part( true );
1311 add_effect( effect_formication, 10_minutes, bp );
1312 }
1313 if( has_bionic( bio_glowy ) && !has_effect( effect_glowy_led ) && one_turn_in( 50_minutes ) &&
1315 add_msg_if_player( m_bad, _( "Your malfunctioning bionic starts to glow!" ) );
1316 add_effect( effect_glowy_led, 5_minutes );
1318 }
1319}
body_part random_body_part(bool main_parts_only)
Returns a random body_part token.
Definition: bodypart.cpp:364
void do_player_death_hurt(const player &target, bool death)
Definition: sounds.cpp:1631
static const bionic_id bio_shakes("bio_shakes")
static const efftype_id effect_glowy_led("glowy_led")
static const efftype_id effect_downed("downed")
static const bionic_id bio_power_weakness("bio_power_weakness")
static const bionic_id bio_dis_shock("bio_dis_shock")
static const bionic_id bio_glowy("bio_glowy")
static const efftype_id effect_visuals("visuals")
static const bionic_id bio_trip("bio_trip")
static const bionic_id bio_dis_acid("bio_dis_acid")
static const itype_id itype_e_handcuffs("e_handcuffs")
static const bionic_id bio_spasm("bio_spasm")
static const bionic_id bio_sleepy("bio_sleepy")
static const bionic_id bio_noise("bio_noise")
static const efftype_id effect_shakes("shakes")
static const efftype_id effect_stunned("stunned")
static const efftype_id effect_formication("formication")
static const bionic_id bio_drain("bio_drain")
static const bionic_id bio_itchy("bio_itchy")
static const bionic_id bio_leaky("bio_leaky")

References _, Creature::add_effect(), add_msg(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), bio_dis_acid, bio_dis_shock, bio_drain, bio_glowy, bio_itchy, bio_leaky, bio_noise, bio_power_weakness, bio_shakes, bio_sleepy, bio_spasm, bio_trip, item::charges, sfx::do_player_death_hurt(), effect_downed, effect_formication, effect_glowy_led, effect_narcosis, effect_shakes, effect_stunned, effect_visuals, g, get_max_power_level(), get_power_level(), has_bionic(), Creature::has_effect(), has_max_power(), hurtall(), in_sleep_state(), is_deaf(), itype_e_handcuffs, m_bad, m_good, m_warning, mod_fatigue(), mod_healthy_mod(), mod_pain(), mod_power_level(), mod_str_bonus(), sounds::movement, Creature::moves, num_bp, one_turn_in(), sfx::play_variant_sound(), pos(), bionic_data::power_trigger, random_body_part(), rng(), sounds::sound(), item::tname(), item::typeId(), and weapon.

Referenced by suffer().

◆ suffer_from_chemimbalance()

void Character::suffer_from_chemimbalance ( )
private

Definition at line 367 of file suffer.cpp.

368{
369 if( one_turn_in( 6_hours ) && !has_trait( trait_NOPAIN ) ) {
370 add_msg_if_player( m_bad, _( "You suddenly feel sharp pain for no reason." ) );
371 mod_pain( 3 * rng( 1, 3 ) );
372 }
373 if( one_turn_in( 6_hours ) ) {
374 int pkilladd = 5 * rng( -1, 2 );
375 if( pkilladd > 0 ) {
376 add_msg_if_player( m_bad, _( "You suddenly feel numb." ) );
377 } else if( ( pkilladd < 0 ) && ( !( has_trait( trait_NOPAIN ) ) ) ) {
378 add_msg_if_player( m_bad, _( "You suddenly ache." ) );
379 }
380 mod_painkiller( pkilladd );
381 }
382 if( one_turn_in( 6_hours ) && !has_effect( effect_sleep ) ) {
383 add_msg_if_player( m_bad, _( "You feel dizzy for a moment." ) );
384 moves -= rng( 10, 30 );
385 }
386 if( one_turn_in( 6_hours ) ) {
387 int hungadd = 5 * rng( -1, 3 );
388 if( hungadd > 0 ) {
389 add_msg_if_player( m_bad, _( "You suddenly feel hungry." ) );
390 } else {
391 add_msg_if_player( m_good, _( "You suddenly feel a little full." ) );
392 }
393 mod_stored_kcal( -10 * hungadd );
394 }
395 if( one_turn_in( 6_hours ) ) {
396 add_msg_if_player( m_bad, _( "You suddenly feel thirsty." ) );
397 mod_thirst( 5 * rng( 1, 3 ) );
398 }
399 if( one_turn_in( 6_hours ) ) {
400 add_msg_if_player( m_good, _( "You feel fatigued all of a sudden." ) );
401 mod_fatigue( 10 * rng( 2, 4 ) );
402 }
403 if( one_turn_in( 8_hours ) ) {
404 if( one_in( 3 ) ) {
406 } else {
407 add_morale( MORALE_FEELING_BAD, -20, -100 );
408 }
409 }
410 if( one_turn_in( 6_hours ) ) {
411 if( one_in( 3 ) ) {
412 add_msg_if_player( m_bad, _( "You suddenly feel very cold." ) );
414 } else {
415 add_msg_if_player( m_bad, _( "You suddenly feel cold." ) );
416 temp_cur.fill( BODYTEMP_COLD );
417 }
419 }
420 if( one_turn_in( 6_hours ) ) {
421 if( one_in( 3 ) ) {
422 add_msg_if_player( m_bad, _( "You suddenly feel very hot." ) );
424 } else {
425 add_msg_if_player( m_bad, _( "You suddenly feel hot." ) );
426 temp_cur.fill( BODYTEMP_HOT );
427 }
429 }
430}
static const trait_id trait_NOPAIN("NOPAIN")

References _, add_morale(), Creature::add_msg_if_player(), BODYTEMP_COLD, BODYTEMP_HOT, BODYTEMP_NORM, BODYTEMP_VERY_COLD, BODYTEMP_VERY_HOT, bp_eyes, effect_sleep, Creature::has_effect(), has_trait(), m_bad, m_good, mod_fatigue(), mod_pain(), mod_painkiller(), mod_stored_kcal(), mod_thirst(), MORALE_FEELING_BAD, MORALE_FEELING_GOOD, Creature::moves, one_in(), one_turn_in(), rng(), temp_cur, and trait_NOPAIN.

Referenced by suffer_while_awake().

◆ suffer_from_other_mutations()

void Character::suffer_from_other_mutations ( )
private

Definition at line 945 of file suffer.cpp.

946{
947 map &here = get_map();
948 if( has_trait( trait_SHARKTEETH ) && one_turn_in( 24_hours ) ) {
949 add_msg_if_player( m_neutral, _( "You shed a tooth!" ) );
950 here.spawn_item( pos(), "bone", 1 );
951 }
952
954 //~Sound of buzzing Insect Wings
955 sounds::sound( pos(), 10, sounds::sound_t::movement, _( "BZZZZZ" ), false, "misc",
956 "insect_wings" );
957 }
958
959 bool wearing_shoes = is_wearing_shoes( side::LEFT ) || is_wearing_shoes( side::RIGHT );
960 int root_vitamins = 0;
961 int root_water = 0;
962 if( has_trait( trait_ROOTS3 ) && here.has_flag( flag_PLOWABLE, pos() ) && !wearing_shoes ) {
963 root_vitamins += 1;
965 root_water += 51;
966 }
967 }
968
969 if( x_in_y( root_vitamins, 576 ) ) {
970 vitamin_mod( vitamin_id( "iron" ), 1, true );
971 vitamin_mod( vitamin_id( "calcium" ), 1, true );
972 mod_healthy_mod( 5, 50 );
973 }
974
975 if( x_in_y( root_water, 2550 ) ) {
976 // Plants draw some crazy amounts of water from the ground in real life,
977 // so these numbers try to reflect that uncertain but large amount
978 // this should take 12 hours to meet your daily needs with ROOTS2, and 8 with ROOTS3
979 mod_thirst( -1 );
980 }
981
982 if( has_trait( trait_SORES ) ) {
983 for( const body_part bp : all_body_parts ) {
984 if( bp == bp_head ) {
985 continue;
986 }
987 int sores_pain = 5 + 0.4 * std::abs( encumb( bp ) );
988 if( get_pain() < sores_pain ) {
989 set_pain( sores_pain );
990 }
991 }
992 }
993 //Web Weavers...weave web
995 // this adds intensity to if its not already there.
996 here.add_field( pos(), fd_web, 1 );
997
998 }
999
1000 // Blind/Deaf for brief periods about once an hour,
1001 // and visuals about once every 30 min.
1002 if( has_trait( trait_PER_SLIME ) ) {
1003 if( one_turn_in( 1_hours ) && !has_effect( effect_deaf ) ) {
1004 add_msg_if_player( m_bad, _( "Suddenly, you can't hear anything!" ) );
1005 add_effect( effect_deaf, rng( 20_minutes, 60_minutes ) );
1006 }
1007 if( one_turn_in( 1_hours ) && !( has_effect( effect_blind ) ) ) {
1008 add_msg_if_player( m_bad, _( "Suddenly, your eyes stop working!" ) );
1009 add_effect( effect_blind, rng( 2_minutes, 6_minutes ) );
1010 }
1011 // Yes, you can be blind and hallucinate at the same time.
1012 // Your post-human biology is truly remarkable.
1013 if( one_turn_in( 30_minutes ) && !( has_effect( effect_visuals ) ) ) {
1014 add_msg_if_player( m_bad, _( "Your visual centers must be acting up…" ) );
1015 add_effect( effect_visuals, rng( 36_minutes, 72_minutes ) );
1016 }
1017 }
1018
1019 if( has_trait( trait_WEB_SPINNER ) && !in_vehicle && one_in( 3 ) ) {
1020 // this adds intensity to if its not already there.
1021 here.add_field( pos(), fd_web, 1 );
1022 }
1023
1024 bool should_mutate = has_trait( trait_UNSTABLE ) && !has_trait( trait_CHAOTIC_BAD ) &&
1025 one_turn_in( 48_hours );
1026 should_mutate |= ( has_trait( trait_CHAOTIC ) || has_trait( trait_CHAOTIC_BAD ) ) &&
1027 one_turn_in( 12_hours );
1028 if( should_mutate ) {
1029 mutate();
1030 }
1031
1032 const bool needs_fire = !has_morale( MORALE_PYROMANIA_NEARFIRE ) &&
1034 if( has_trait( trait_PYROMANIA ) && needs_fire && !in_sleep_state() &&
1035 calendar::once_every( 2_hours ) ) {
1036 add_morale( MORALE_PYROMANIA_NOFIRE, -1, -30, 24_hours, 24_hours, true );
1037 if( calendar::once_every( 4_hours ) ) {
1038 const translation smokin_hot_fiyah =
1039 SNIPPET.random_from_category( "pyromania_withdrawal" ).value_or( translation() );
1040 add_msg_if_player( m_bad, "%s", smokin_hot_fiyah );
1041 }
1042 }
1044 calendar::once_every( 2_hours ) ) {
1046 const translation snip = SNIPPET.random_from_category( "killer_withdrawal" ).value_or(
1047 translation() );
1048 add_msg_if_player( m_bad, "%s", snip );
1049 }
1050 add_morale( MORALE_KILLER_NEED_TO_KILL, -1, -30, 24_hours, 24_hours );
1051 }
1052}
bool has_morale(const morale_type &type) const
Definition: character.cpp:9058
void spawn_item(const tripoint &p, const itype_id &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
Definition: map.cpp:4195
const morale_type MORALE_KILLER_HAS_KILLED("morale_killer_has_killed")
const morale_type MORALE_PYROMANIA_STARTFIRE("morale_pyromania_startfire")
const morale_type MORALE_KILLER_NEED_TO_KILL("morale_killer_need_to_kill")
const morale_type MORALE_PYROMANIA_NEARFIRE("morale_pyromania_nearfire")
const morale_type MORALE_PYROMANIA_NOFIRE("morale_pyromania_nofire")
static const efftype_id effect_blind("blind")
static const trait_id trait_PER_SLIME("PER_SLIME")
static const trait_id trait_SHARKTEETH("SHARKTEETH")
static const trait_id trait_CHAOTIC("CHAOTIC")
static const trait_id trait_UNSTABLE("UNSTABLE")
static const trait_id trait_PYROMANIA("PYROMANIA")
static const efftype_id effect_deaf("deaf")
static const trait_id trait_WEB_WEAVER("WEB_WEAVER")
static const trait_id trait_CHAOTIC_BAD("CHAOTIC_BAD")
static const trait_id trait_WINGS_INSECT("WINGS_INSECT")
static const trait_id trait_SORES("SORES")
static const trait_id trait_KILLER("KILLER")
static const trait_id trait_WEB_SPINNER("WEB_SPINNER")
static const std::string flag_PLOWABLE("PLOWABLE")
static const trait_id trait_ROOTS3("ROOTS3")

References _, Creature::add_effect(), map::add_field(), add_morale(), Creature::add_msg_if_player(), all_body_parts, bp_head, effect_blind, effect_deaf, effect_visuals, encumb(), fd_web, flag_PLOWABLE(), get_map(), Creature::get_pain(), get_thirst(), has_active_mutation(), Creature::has_effect(), map::has_flag(), has_morale(), has_trait(), in_sleep_state(), in_vehicle, is_wearing_shoes(), LEFT, m_bad, m_neutral, mod_healthy_mod(), mod_thirst(), MORALE_KILLER_HAS_KILLED, MORALE_KILLER_NEED_TO_KILL, MORALE_PYROMANIA_NEARFIRE, MORALE_PYROMANIA_NOFIRE, MORALE_PYROMANIA_STARTFIRE, sounds::movement, mutate(), calendar::once_every(), one_in(), one_turn_in(), pos(), snippet_library::random_from_category(), RIGHT, rng(), set_pain(), SNIPPET, sounds::sound(), map::spawn_item(), trait_CHAOTIC, trait_CHAOTIC_BAD, trait_KILLER, trait_PER_SLIME, trait_PYROMANIA, trait_ROOTS3, trait_SHARKTEETH, trait_SORES, trait_UNSTABLE, trait_WEB_SPINNER, trait_WEB_WEAVER, trait_WINGS_INSECT, turgid, vitamin_mod(), and x_in_y().

Referenced by suffer().

◆ suffer_from_radiation()

void Character::suffer_from_radiation ( )
private

Definition at line 1054 of file suffer.cpp.

1055{
1056 map &here = get_map();
1057 // checking for radioactive items in inventory
1058 const int item_radiation = leak_level( "RADIOACTIVE" );
1059 const int map_radiation = here.get_radiation( pos() );
1060 float rads = map_radiation / 100.0f + item_radiation / 10.0f;
1061
1062 int rad_mut = 0;
1063 if( has_trait( trait_RADIOACTIVE3 ) ) {
1064 rad_mut = 3;
1065 } else if( has_trait( trait_RADIOACTIVE2 ) ) {
1066 rad_mut = 2;
1067 } else if( has_trait( trait_RADIOACTIVE1 ) ) {
1068 rad_mut = 1;
1069 }
1070
1071 // Spread less radiation when sleeping (slower metabolism etc.)
1072 // Otherwise it can quickly get to the point where you simply can't sleep at all
1073 const bool rad_mut_proc = rad_mut > 0 && x_in_y( rad_mut, to_turns<int>( in_sleep_state() ?
1074 3_hours : 30_minutes ) );
1075
1076 bool has_helmet = false;
1077 const bool power_armored = is_wearing_power_armor( &has_helmet );
1078 const bool rad_resist = power_armored || worn_with_flag( flag_RAD_RESIST );
1079
1080 if( rad_mut > 0 ) {
1081 const bool kept_in = is_rad_immune() || ( rad_resist && !one_in( 4 ) );
1082 if( kept_in ) {
1083 // As if standing on a map tile with radiation level equal to rad_mut
1084 rads += rad_mut / 100.0f;
1085 }
1086
1087 if( rad_mut_proc && !kept_in ) {
1088 // Irradiate a random nearby point
1089 // If you can't, irradiate the player instead
1090 tripoint rad_point = pos() + point( rng( -3, 3 ), rng( -3, 3 ) );
1091 // TODO: Radioactive vehicles?
1092 if( here.get_radiation( rad_point ) < rad_mut ) {
1093 here.adjust_radiation( rad_point, 1 );
1094 } else {
1095 rads += rad_mut;
1096 }
1097 }
1098 }
1099
1100 // Used to control vomiting from radiation to make it not-annoying
1101 bool radiation_increasing = irradiate( rads );
1102
1103 if( radiation_increasing && calendar::once_every( 3_minutes ) && has_bionic( bio_geiger ) ) {
1105 _( "You feel an anomalous sensation coming from "
1106 "your radiation sensors." ) );
1107 }
1108
1109 if( calendar::once_every( 15_minutes ) ) {
1110 if( get_rad() < 0 ) {
1111 set_rad( 0 );
1112 } else if( get_rad() > 2000 ) {
1113 set_rad( 2000 );
1114 }
1115 if( get_option<bool>( "RAD_MUTATION" ) && rng( 100, 10000 ) < get_rad() ) {
1116 mutate();
1117 mod_rad( -50 );
1118 } else if( get_rad() > 50 && rng( 1, 3000 ) < get_rad() && ( stomach.get_calories() > 0 ||
1119 radiation_increasing || !in_sleep_state() ) ) {
1120 vomit();
1121 mod_rad( -1 );
1122 }
1123 }
1124
1125 const bool radiogenic = has_trait( trait_RADIOGENIC );
1126 if( radiogenic && calendar::once_every( 30_minutes ) && get_rad() > 0 ) {
1127 // At 200 irradiation, twice as fast as REGEN
1128 if( x_in_y( get_rad(), 200 ) ) {
1129 healall( 1 );
1130 if( rad_mut == 0 ) {
1131 // Don't heal radiation if we're generating it naturally
1132 // That would counter the main downside of radioactivity
1133 mod_rad( -5 );
1134 }
1135 }
1136 }
1137
1138 if( !radiogenic && get_rad() > 0 ) {
1139 // Even if you heal the radiation itself, the damage is done.
1140 const int hmod = get_healthy_mod();
1141 if( hmod > 200 - get_rad() ) {
1142 set_healthy_mod( std::max( -200, 200 - get_rad() ) );
1143 }
1144 }
1145
1146 if( get_rad() > 200 && calendar::once_every( 10_minutes ) && x_in_y( get_rad(), 1000 ) ) {
1147 hurtall( 1, nullptr );
1148 mod_rad( -5 );
1149 }
1150
1151 if( !reactor_plut && !tank_plut && !slow_rad ) {
1152 return;
1153 }
1154 // Microreactor CBM and supporting bionics
1156 //first do the filtering of plutonium from storage to reactor
1157 if( tank_plut > 0 ) {
1158 int plut_trans;
1160 plut_trans = tank_plut * 0.025;
1161 } else {
1162 plut_trans = tank_plut * 0.005;
1163 }
1164 if( plut_trans < 1 ) {
1165 plut_trans = 1;
1166 }
1167 tank_plut -= plut_trans;
1168 reactor_plut += plut_trans;
1169 }
1170 //leaking radiation, reactor is unshielded, but still better than a simple tank
1171 slow_rad += ( ( tank_plut * 0.1 ) + ( reactor_plut * 0.01 ) );
1172 //begin power generation
1173 if( reactor_plut > 0 ) {
1174 int power_gen = 0;
1175 if( has_bionic( bio_advreactor ) ) {
1176 if( ( reactor_plut * 0.05 ) > 2000 ) {
1177 power_gen = 2000;
1178 } else {
1179 power_gen = reactor_plut * 0.05;
1180 if( power_gen < 1 ) {
1181 power_gen = 1;
1182 }
1183 }
1184 slow_rad += ( power_gen * 3 );
1185 while( slow_rad >= 50 ) {
1186 if( power_gen >= 1 ) {
1187 slow_rad -= 50;
1188 power_gen -= 1;
1189 reactor_plut -= 1;
1190 } else {
1191 break;
1192 }
1193 }
1194 } else if( has_bionic( bio_reactor ) ) {
1195 if( ( reactor_plut * 0.025 ) > 500 ) {
1196 power_gen = 500;
1197 } else {
1198 power_gen = reactor_plut * 0.025;
1199 if( power_gen < 1 ) {
1200 power_gen = 1;
1201 }
1202 }
1203 slow_rad += ( power_gen * 3 );
1204 }
1205 reactor_plut -= power_gen;
1206 while( power_gen >= 250 ) {
1207 apply_damage( nullptr, bodypart_id( "torso" ), 1 );
1208 mod_pain( 1 );
1210 _( "Your chest burns as your power systems overload!" ) );
1211 mod_power_level( 50_kJ );
1212 power_gen -= 60; // ten units of power lost due to short-circuiting into you
1213 }
1214 mod_power_level( units::from_kilojoule( power_gen ) );
1215 }
1216 } else {
1217 slow_rad += ( reactor_plut + tank_plut ) * 40;
1218 //plutonium in body without any kind of container. Not good at all.
1219 reactor_plut *= 0.6;
1220 tank_plut *= 0.6;
1221 }
1222 while( slow_rad >= 1000 ) {
1223 mod_rad( 1 );
1224 slow_rad -= 1000;
1225 }
1226}
void adjust_radiation(const tripoint &p, int delta)
Increment the radiation in the given tile by the given delta (decrement it if delta is negative)
Definition: map.cpp:4059
int get_radiation(const tripoint &p) const
Definition: map.cpp:4035
static const bionic_id bio_geiger("bio_geiger")
static const std::string flag_RAD_RESIST("RAD_RESIST")
static const bionic_id bio_reactor("bio_reactor")
static const bionic_id bio_plut_filter("bio_plut_filter")
static const bionic_id bio_advreactor("bio_advreactor")

References _, Creature::add_msg_if_player(), map::adjust_radiation(), apply_damage(), bio_advreactor, bio_geiger, bio_plut_filter, bio_reactor, flag_RAD_RESIST(), units::from_kilojoule(), stomach_contents::get_calories(), get_healthy_mod(), get_map(), get_rad(), map::get_radiation(), has_active_bionic(), has_bionic(), has_trait(), healall(), hurtall(), in_sleep_state(), irradiate(), is_rad_immune(), is_wearing_power_armor(), leak_level(), m_bad, m_warning, mod_pain(), mod_power_level(), mod_rad(), mutate(), calendar::once_every(), one_in(), pos(), reactor_plut, rng(), set_healthy_mod(), set_rad(), slow_rad, stomach, tank_plut, trait_RADIOACTIVE1, trait_RADIOACTIVE2, trait_RADIOACTIVE3, trait_RADIOGENIC, vomit(), worn_with_flag(), and x_in_y().

Referenced by suffer().

◆ suffer_from_schizophrenia()

void Character::suffer_from_schizophrenia ( )
private

Definition at line 432 of file suffer.cpp.

433{
434 std::string i_name_w;
435 if( !weapon.is_null() ) {
436 i_name_w = weapon.has_var( "item_label" ) ? weapon.get_var( "item_label" ) :
437 //~ %1$s: weapon name
438 string_format( _( "your %1$s" ), weapon.type_name() );
439 }
440 // Start with the effects that both NPCs and avatars can suffer from
441 // Delusions
442 if( one_turn_in( 8_hours ) ) {
443 if( rng( 1, 20 ) > 5 ) { // 75% chance
444 const translation snip = SNIPPET.random_from_category( "schizo_delusion_paranoid" ).value_or(
445 translation() );
446 add_msg_if_player( m_warning, "%s", snip );
447 add_morale( MORALE_FEELING_BAD, -20, -100 );
448 } else { // 25% chance
449 const translation snip = SNIPPET.random_from_category( "schizo_delusion_grandiose" ).value_or(
450 translation() );
451 add_msg_if_player( m_good, "%s", snip );
453 }
454 return;
455 }
456 // Formication
457 if( one_turn_in( 6_hours ) ) {
458 const translation snip = SNIPPET.random_from_category( "schizo_formication" ).value_or(
459 translation() );
460 body_part bp = random_body_part( true );
461 add_effect( effect_formication, 45_minutes, bp );
462 add_msg_if_player( m_bad, "%s", snip );
463 return;
464 }
465 // Numbness
466 if( one_turn_in( 4_hours ) ) {
467 add_msg_if_player( m_bad, _( "You suddenly feel so numb…" ) );
468 mod_painkiller( 25 );
469 return;
470 }
471 // Hallucination
472 if( one_turn_in( 6_hours ) ) {
473 add_effect( effect_hallu, 6_hours );
474 return;
475 }
476 // Visuals
477 if( one_turn_in( 2_hours ) ) {
478 add_effect( effect_visuals, rng( 15_turns, 60_turns ) );
479 return;
480 }
481 // Shaking
482 if( !has_effect( effect_valium ) && one_turn_in( 4_hours ) ) {
483 add_msg_player_or_npc( m_bad, _( "You start to shake uncontrollably." ),
484 _( "<npcname> starts to shake uncontrollably." ) );
485 add_effect( effect_shakes, rng( 2_minutes, 5_minutes ) );
486 return;
487 }
488 // Shout
489 if( one_turn_in( 4_hours ) ) {
490 shout( SNIPPET.random_from_category( "schizo_self_shout" ).value_or( translation() ).translated() );
491 return;
492 }
493 // Drop weapon
494 if( one_turn_in( 2_days ) && !weapon.is_null() ) {
495 const translation snip = SNIPPET.random_from_category( "schizo_weapon_drop" ).value_or(
496 translation() );
497 std::string str = string_format( snip, i_name_w );
498 str[0] = toupper( str[0] );
499
500 add_msg_if_player( m_bad, "%s", str );
501 item_location loc( *this, &weapon );
502 drop( loc, pos() );
503 return;
504 }
505 // Talk to self
506 if( one_turn_in( 4_hours ) ) {
507 const translation snip = SNIPPET.random_from_category( "schizo_self_talk" ).value_or(
508 translation() );
509 add_msg( _( "%1$s says: \"%2$s\"" ), name, snip );
510 return;
511 }
512
513 // effects of this point are entirely internal, so NPCs can't suffer from them
514 if( is_npc() ) {
515 return;
516 }
517 // Sound
518 if( one_turn_in( 4_hours ) ) {
519 sound_hallu();
520 }
521 // Follower turns hostile
522 if( one_turn_in( 4_hours ) ) {
523 std::vector<shared_ptr_fast<npc>> followers = overmap_buffer.get_npcs_near_player( 12 );
524
525 std::string who_gets_angry = name;
526 if( !followers.empty() ) {
527 who_gets_angry = random_entry_ref( followers )->name;
528 }
529 add_msg_if_player( m_bad, _( "%1$s gets angry!" ), who_gets_angry );
530 return;
531 }
532
533 // Monster dies
534 if( one_turn_in( 6_hours ) ) {
535 // TODO: move to monster group json
536 static const std::array<mtype_id, 5> monsters = { {
538 }
539 };
540 add_msg_if_player( _( "%s dies!" ), random_entry_ref( monsters )->nname() );
541 return;
542 }
543
544 // Limb Breaks
545 if( one_turn_in( 4_hours ) ) {
546 const translation snip = SNIPPET.random_from_category( "broken_limb" ).value_or( translation() );
547 add_msg_if_player( m_bad, "%s", snip );
548 return;
549 }
550
551 // NPC chat
552 if( one_turn_in( 4_hours ) ) {
553 std::string i_name = Name::generate( one_in( 2 ) );
554
555 std::string i_talk = SNIPPET.expand( SNIPPET.random_from_category( "<lets_talk>" ).value_or(
556 translation() ).translated() );
557 parse_tags( i_talk, *this, *this );
558
559 add_msg_if_player( _( "%1$s says: \"%2$s\"" ), i_name, i_talk );
560 return;
561 }
562
563 // Skill raise
564 if( one_turn_in( 12_hours ) ) {
565 skill_id raised_skill = Skill::random_skill();
566 add_msg_if_player( m_good, _( "You increase %1$s to level %2$d." ), raised_skill.obj().name(),
567 get_skill_level( raised_skill ) + 1 );
568 return;
569 }
570
571 // Talking weapon
572 if( !weapon.is_null() ) {
573 // If player has a weapon, picks a message from said weapon
574 // Weapon tells player to kill a monster if any are nearby
575 // Weapon is concerned for player if bleeding
576 // Weapon is concerned for itself if damaged
577 // Otherwise random chit-chat
578 std::vector<weak_ptr_fast<monster>> mons = g->all_monsters().items;
579
580 std::string i_talk_w;
581 bool does_talk = false;
582 if( !mons.empty() && one_turn_in( 12_minutes ) ) {
583 std::vector<std::string> seen_mons;
584 for( weak_ptr_fast<monster> &n : mons ) {
585 if( sees( *n.lock() ) ) {
586 seen_mons.emplace_back( n.lock()->get_name() );
587 }
588 }
589 if( !seen_mons.empty() ) {
590 const translation talk_w = SNIPPET.random_from_category( "schizo_weapon_talk_monster" ).value_or(
591 translation() );
592 i_talk_w = string_format( talk_w, random_entry_ref( seen_mons ) );
593 does_talk = true;
594 }
595 }
596 if( !does_talk && has_effect( effect_bleed ) && one_turn_in( 5_minutes ) ) {
597 i_talk_w = SNIPPET.random_from_category( "schizo_weapon_talk_bleeding" ).value_or(
598 translation() ).translated();
599 does_talk = true;
600 } else if( weapon.damage() >= weapon.max_damage() / 3 && one_turn_in( 1_hours ) ) {
601 i_talk_w = SNIPPET.random_from_category( "schizo_weapon_talk_damaged" ).value_or(
602 translation() ).translated();
603 does_talk = true;
604 } else if( one_turn_in( 4_hours ) ) {
605 i_talk_w = SNIPPET.random_from_category( "schizo_weapon_talk_misc" ).value_or(
606 translation() ).translated();
607 does_talk = true;
608 }
609 if( does_talk ) {
610 add_msg_if_player( _( "%1$s says: \"%2$s\"" ), i_name_w, i_talk_w );
611 return;
612 }
613 }
614}
static skill_id random_skill()
Definition: skill.cpp:205
double get_var(const std::string &name, double default_value) const
Definition: item.cpp:1030
int max_damage() const
Maximum amount of damage to an item (state before destroyed)
Definition: item.cpp:6221
bool has_var(const std::string &name) const
Whether the variable is defined at all.
Definition: item.cpp:1075
int damage() const
How much damage has the item sustained?
Definition: item.cpp:696
std::vector< shared_ptr_fast< npc > > get_npcs_near_player(int radius)
Same as get_npcs_near(int,int,int,int) but uses player position as center.
std::string expand(const std::string &str) const
Expand the string by recursively replacing tags in angle brackets (<>) with random snippets from the ...
std::weak_ptr< T > weak_ptr_fast
Definition: memory_fast.h:17
void parse_tags(std::string &phrase, const Character &u, const Character &me, const itype_id &item_type=itype_id::NULL_ID())
Definition: npctalk.cpp:1582
static const efftype_id effect_bleed("bleed")
static const mtype_id mon_zombie_cop("mon_zombie_cop")
static const efftype_id effect_hallu("hallu")
static const mtype_id mon_zombie_fireman("mon_zombie_fireman")
static const mtype_id mon_zombie_fat("mon_zombie_fat")
static const mtype_id mon_zombie_soldier("mon_zombie_soldier")
static const mtype_id mon_zombie("mon_zombie")
static const efftype_id effect_valium("valium")

References _, Creature::add_effect(), add_morale(), add_msg(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), item::damage(), drop(), effect_bleed, effect_formication, effect_hallu, effect_shakes, effect_valium, effect_visuals, snippet_library::expand(), g, Name::generate(), overmapbuffer::get_npcs_near_player(), get_skill_level(), item::get_var(), Creature::has_effect(), item::has_var(), Creature::is_npc(), item::is_null(), m_bad, m_good, m_warning, item::max_damage(), mod_painkiller(), mon_zombie, mon_zombie_cop, mon_zombie_fat, mon_zombie_fireman, mon_zombie_soldier, MORALE_FEELING_BAD, MORALE_FEELING_GOOD, name, Skill::name(), string_id< T >::obj(), one_in(), one_turn_in(), overmap_buffer, parse_tags(), pos(), random_body_part(), random_entry_ref(), snippet_library::random_from_category(), Skill::random_skill(), rng(), sees(), shout(), SNIPPET, sound_hallu(), string_format(), item::type_name(), and weapon.

Referenced by suffer_while_awake().

◆ suffer_from_stimulants()

void Character::suffer_from_stimulants ( int  current_stim)
private

Definition at line 1343 of file suffer.cpp.

1344{
1345 // Stim +250 kills
1346 if( current_stim > 210 ) {
1347 if( one_turn_in( 2_minutes ) && !has_effect( effect_downed ) ) {
1348 add_msg_if_player( m_bad, _( "Your muscles spasm!" ) );
1349 if( !has_effect( effect_downed ) ) {
1350 add_msg_if_player( m_bad, _( "You fall to the ground!" ) );
1351 add_effect( effect_downed, rng( 6_turns, 20_turns ) );
1352 }
1353 }
1354 }
1355 if( current_stim > 110 ) {
1356 if( !has_effect( effect_shakes ) && calendar::once_every( 10_minutes ) ) {
1357 add_msg_if_player( _( "You shake uncontrollably." ) );
1358 add_effect( effect_shakes, 15_minutes + 1_turns );
1359 }
1360 }
1361 if( current_stim > 75 ) {
1362 if( calendar::once_every( 5_minutes ) && !has_effect( effect_nausea ) ) {
1363 add_msg_if_player( _( "You feel nauseous…" ) );
1364 add_effect( effect_nausea, 5_minutes );
1365 }
1366 }
1367
1368 //stim -200 or painkillers 240 kills
1369 if( current_stim < -160 || get_painkiller() > 200 ) {
1370 if( one_turn_in( 3_minutes ) && !in_sleep_state() ) {
1371 add_msg_if_player( m_bad, _( "You black out!" ) );
1372 const time_duration dur = rng( 30_minutes, 60_minutes );
1373 add_effect( effect_downed, dur );
1374 fall_asleep( dur );
1375 }
1376 }
1377 if( current_stim < -60 || get_painkiller() > 130 ) {
1378 if( calendar::once_every( 10_minutes ) ) {
1379 add_msg_if_player( m_warning, _( "You feel tired…" ) );
1380 mod_fatigue( rng( 1, 2 ) );
1381 }
1382 }
1383}
static const efftype_id effect_nausea("nausea")

References _, Creature::add_effect(), Creature::add_msg_if_player(), effect_downed, effect_nausea, effect_shakes, fall_asleep(), get_painkiller(), Creature::has_effect(), in_sleep_state(), m_bad, m_warning, mod_fatigue(), calendar::once_every(), one_turn_in(), and rng().

Referenced by suffer().

◆ suffer_from_sunburn()

void Character::suffer_from_sunburn ( )
private

Definition at line 810 of file suffer.cpp.

811{
813 return;
814 }
815
816 std::string sunlight_effect;
818 // Albinism and datura have the same effects, once per minute on average
819 if( !one_turn_in( 1_minutes ) ) {
820 return;
821 }
822 sunlight_effect = _( "The sunlight is really irritating" );
823 } else if( has_trait( trait_SUNBURN ) ) {
824 // Sunburn effects occur about 3 times per minute
825 if( !one_turn_in( 20_seconds ) ) {
826 return;
827 }
828 sunlight_effect = _( "The sunlight burns" );
829 }
830
831 // Sunglasses can keep the sun off the eyes.
832 if( !has_bionic( bio_sunglasses ) &&
833 !( wearing_something_on( bodypart_id( "eyes" ) ) &&
835 add_msg_if_player( m_bad, _( "%s your eyes." ), sunlight_effect );
836 // Pain (1/60) or loss of focus (59/60)
837 if( one_turn_in( 1_minutes ) ) {
838 mod_pain( 1 );
839 } else {
840 focus_pool --;
841 }
842 }
843 // Umbrellas can keep the sun off the skin
844 if( weapon.has_flag( "RAIN_PROTECT" ) ) {
845 return;
846 }
847
848 std::map<bodypart_id, float> bp_exposure = bodypart_exposure();
849
850 // Minimum exposure threshold for pain
851 const float MIN_EXPOSURE = 0.01f;
852 // Count how many body parts are above the threshold
853 int count_affected_bp = 0;
854 // Get the most exposed body part, and how exposed it is. This is to tell the player what body
855 // part is most irritated by sun, so they know what needs to be covered up better.
856 bodypart_id most_exposed_bp;
857 float max_exposure = 0.0f;
858 // Check each bodypart with exposure above the minimum
859 for( const std::pair<const bodypart_id, float> &bp_exp : bp_exposure ) {
860 const float exposure = bp_exp.second;
861 // Skip minimally-exposed parts, and skip the eyes (handled by sunglasses)
862 if( exposure <= MIN_EXPOSURE || bp_exp.first == bodypart_id( "eyes" ) ) {
863 continue;
864 }
865 ++count_affected_bp;
866 if( exposure > max_exposure ) {
867 max_exposure = exposure;
868 most_exposed_bp = bp_exp.first;
869 }
870 }
871
872 // If all body parts are protected, there is no suffering
873 if( count_affected_bp == 0 || !most_exposed_bp ) {
874 return;
875 }
876
877 // Check if both arms/legs are affected
878 int count_limbs = 1;
879 const bodypart_id &other_bp = most_exposed_bp->opposite_part;
880 const bodypart_id &other_bp_rev = other_bp->opposite_part;
881 // If these are different, we have a left/right part like a leg or arm.
882 // If same, it's a central body part with no opposite, like head or torso.
883 // Only used to generate a simpler message when both arms or both legs are affected.
884 if( other_bp != other_bp_rev ) {
885 const auto found = bp_exposure.find( other_bp );
886 // Is opposite part exposed?
887 if( found != bp_exposure.end() && found->second > MIN_EXPOSURE ) {
888 ++count_limbs;
889 }
890 }
891 // Get singular or plural body part name; append "and other body parts" if appropriate
892 std::string bp_name = body_part_name( most_exposed_bp, count_limbs );
893 if( count_affected_bp == count_limbs ) {
894 add_msg_if_player( m_bad, _( "%s your %s." ), sunlight_effect, bp_name );
895 } else {
896 add_msg_if_player( m_bad, _( "%s your %s and other body parts." ), sunlight_effect,
897 bp_name );
898 }
899
900 // Wake up from skin irritation/burning
901 if( has_effect( effect_sleep ) ) {
902 wake_up();
903 }
904
905 // Solar Sensitivity (SUNBURN) trait causes injury to exposed parts
906 if( has_trait( trait_SUNBURN ) ) {
907 mod_pain( 1 );
908 // Check exposure of all body parts
909 for( const std::pair<const bodypart_id, float> &bp_exp : bp_exposure ) {
910 const bodypart_id &this_part = bp_exp.first;
911 const float exposure = bp_exp.second;
912 // Skip parts with adequate protection
913 if( exposure <= MIN_EXPOSURE ) {
914 continue;
915 }
916 // Don't damage eyes directly, since it takes from head HP (in other words, your head
917 // won't be destroyed if only your eyes are exposed).
918 if( this_part == bodypart_id( "eyes" ) ) {
919 continue;
920 }
921 // Exposure percentage determines likelihood of injury
922 // 10% exposure is 10% chance of injury, naked = 100% chance
923 if( x_in_y( exposure, 1.0 ) ) {
924 // Because hands and feet share an HP pool with arms and legs, and the mouth shares
925 // an HP pool with the head, those parts take an unfair share of damage in relation
926 // to the torso, which only has one part. Increase torso damage to balance this.
927 if( this_part == bodypart_id( "torso" ) ) {
928 apply_damage( nullptr, this_part, 2 );
929 } else {
930 apply_damage( nullptr, this_part, 1 );
931 }
932 }
933 }
934 } else {
935 // Albinism/datura causes pain (1/60) or focus loss (59/60)
936 if( one_turn_in( 1_minutes ) ) {
937 mod_pain( 1 );
938 } else {
939 focus_pool --;
940 }
941 }
942}
std::map< bodypart_id, float > bodypart_exposure()
Map body parts to their total exposure, from 0.0 (fully covered) to 1.0 (buck naked).
Definition: suffer.cpp:783
static const trait_id trait_ALBINO("ALBINO")
static const std::string flag_BLIND("BLIND")
static const trait_id trait_SUNBURN("SUNBURN")
static const std::string flag_SUN_GLASSES("SUN_GLASSES")
static const bionic_id bio_sunglasses("bio_sunglasses")

References _, Creature::add_msg_if_player(), apply_damage(), bio_sunglasses, body_part_name(), bodypart_exposure(), effect_datura, effect_sleep, flag_BLIND(), flag_SUN_GLASSES(), focus_pool, has_bionic(), Creature::has_effect(), item::has_flag(), has_trait(), m_bad, mod_pain(), one_turn_in(), trait_ALBINO, trait_SUNBURN, wake_up(), weapon, wearing_something_on(), worn_with_flag(), and x_in_y().

Referenced by suffer_in_sunlight().

◆ suffer_in_sunlight()

void Character::suffer_in_sunlight ( )
private

Definition at line 718 of file suffer.cpp.

719{
720 double sleeve_factor = armwear_factor();
721 const bool has_hat = wearing_something_on( bodypart_id( "head" ) );
722 const bool leafy = has_trait( trait_LEAVES ) || has_trait( trait_LEAVES2 ) ||
724 const bool leafier = has_trait( trait_LEAVES2 ) || has_trait( trait_LEAVES3 );
725 const bool leafiest = has_trait( trait_LEAVES3 );
726 int sunlight_nutrition = 0;
727 if( leafy && get_map().is_outside( pos() ) && ( g->light_level( pos().z ) >= 40 ) ) {
728 const float weather_factor = ( get_weather().weather_id->sun_intensity >=
729 sun_intensity_type::normal ) ? 1.0 : 0.5;
730 const int player_local_temp = get_weather().get_temperature( pos() );
731 int flux = ( player_local_temp - 65 ) / 2;
732 if( !has_hat ) {
733 sunlight_nutrition += ( 100 + flux ) * weather_factor;
734 }
735 if( leafier ) {
736 int rate = ( ( 100 * sleeve_factor ) + flux ) * 2;
737 sunlight_nutrition += ( rate * ( leafiest ? 2 : 1 ) ) * weather_factor;
738 }
739 }
740
741 if( x_in_y( sunlight_nutrition, 18000 ) ) {
742 vitamin_mod( vitamin_id( "vitA" ), 1, true );
743 vitamin_mod( vitamin_id( "vitC" ), 1, true );
744 }
745
746 if( x_in_y( sunlight_nutrition, 12000 ) ) {
747 mod_stored_kcal( 10 );
748 stomach.ate();
749 }
750
751 if( !g->is_in_sunlight( pos() ) ) {
752 return;
753 }
754
757 }
758
760 get_weather().weather_id->sun_intensity >= sun_intensity_type::high ) {
761 mod_str_bonus( -1 );
762 mod_dex_bonus( -1 );
763 add_miss_reason( _( "The sunlight distracts you." ), 1 );
764 mod_int_bonus( -1 );
765 mod_per_bonus( -1 );
766 }
767 if( has_trait( trait_TROGLO2 ) ) {
768 mod_str_bonus( -1 );
769 mod_dex_bonus( -1 );
770 add_miss_reason( _( "The sunlight distracts you." ), 1 );
771 mod_int_bonus( -1 );
772 mod_per_bonus( -1 );
773 }
774 if( has_trait( trait_TROGLO3 ) ) {
775 mod_str_bonus( -4 );
776 mod_dex_bonus( -4 );
777 add_miss_reason( _( "You can't stand the sunlight!" ), 4 );
778 mod_int_bonus( -4 );
779 mod_per_bonus( -4 );
780 }
781}
void suffer_from_sunburn()
Definition: suffer.cpp:810
double armwear_factor() const
Same as footwear factor, but for arms.
Definition: character.cpp:8879
weather_type_id weather_id
Definition: weather.h:193
sun_intensity_type sun_intensity
Definition: weather_type.h:121
static const trait_id trait_LEAVES("LEAVES")
static const trait_id trait_TROGLO3("TROGLO3")
static const trait_id trait_LEAVES2("LEAVES2")
static const trait_id trait_TROGLO("TROGLO")
static const trait_id trait_TROGLO2("TROGLO2")
static const trait_id trait_LEAVES3("LEAVES3")

References _, add_miss_reason(), armwear_factor(), stomach_contents::ate(), effect_datura, g, get_map(), weather_manager::get_temperature(), get_weather(), Creature::has_effect(), has_trait(), high, mod_dex_bonus(), mod_int_bonus(), mod_per_bonus(), mod_stored_kcal(), mod_str_bonus(), normal, pos(), stomach, suffer_from_sunburn(), weather_type::sun_intensity, trait_ALBINO, trait_LEAVES, trait_LEAVES2, trait_LEAVES3, trait_SUNBURN, trait_TROGLO, trait_TROGLO2, trait_TROGLO3, vitamin_mod(), wearing_something_on(), weather_manager::weather_id, and x_in_y().

Referenced by suffer().

◆ suffer_mutation_power()

void Character::suffer_mutation_power ( const mutation_branch mdata,
char_trait_data tdata 
)
private

Definition at line 203 of file suffer.cpp.

204{
205 if( tdata.powered && tdata.charge > 0 ) {
206 // Already-on units just lose a bit of charge
207 tdata.charge--;
208 } else {
209 // Not-on units, or those with zero charge, have to pay the power cost
210 if( mdata.cooldown > 0 ) {
211 tdata.powered = true;
212 tdata.charge = mdata.cooldown - 1;
213 }
214 if( mdata.hunger ) {
215 // does not directly modify hunger, but burns kcal
216 mod_stored_nutr( mdata.cost );
219 _( "You're too malnourished to keep your %s going." ),
220 mdata.name() );
221 tdata.powered = false;
222 }
223 }
224 if( mdata.thirst ) {
225 mod_thirst( mdata.cost );
226 // Well into Dehydrated
229 _( "You're too dehydrated to keep your %s going." ),
230 mdata.name() );
231 tdata.powered = false;
232 }
233 }
234 if( mdata.fatigue ) {
235 mod_fatigue( mdata.cost );
236 // Exhausted
239 _( "You're too exhausted to keep your %s going." ),
240 mdata.name() );
241 tdata.powered = false;
242 }
243 }
244 if( !tdata.powered ) {
245 apply_mods( mdata.id, false );
246 }
247 }
248}
constexpr float underweight

References _, Creature::add_msg_if_player(), apply_mods(), bmi(), char_trait_data::charge, mutation_branch::cooldown, mutation_branch::cost, dehydrated, exhausted, mutation_branch::fatigue, get_fatigue(), get_thirst(), mutation_branch::hunger, mutation_branch::id, m_warning, mod_fatigue(), mod_stored_nutr(), mod_thirst(), mutation_branch::name(), char_trait_data::powered, mutation_branch::thirst, and character_weight_category::underweight.

Referenced by suffer().

◆ suffer_water_damage()

void Character::suffer_water_damage ( const mutation_branch mdata)
private

suffer() subcalls

Definition at line 183 of file suffer.cpp.

184{
185 for( const std::pair<const bodypart_str_id, bodypart> &elem : get_body() ) {
186 const float wetness_percentage = static_cast<float>( body_wetness[elem.first->token] ) /
187 drench_capacity[elem.first->token];
188 const int dmg = mdata.weakness_to_water * wetness_percentage;
189 if( dmg > 0 ) {
190 apply_damage( nullptr, elem.first, dmg );
191 add_msg_player_or_npc( m_bad, _( "Your %s is damaged by the water." ),
192 _( "<npcname>'s %s is damaged by the water." ),
193 body_part_name( elem.first ) );
194 } else if( dmg < 0 && elem.second.is_at_max_hp() ) {
195 heal( elem.first, std::abs( dmg ) );
196 add_msg_player_or_npc( m_good, _( "Your %s is healed by the water." ),
197 _( "<npcname>'s %s is healed by the water." ),
198 body_part_name( elem.first ) );
199 }
200 }
201}
int weakness_to_water
maximum damage dealt by water every minute when wet.
Definition: mutation.h:168

References _, Creature::add_msg_player_or_npc(), apply_damage(), body_part_name(), body_wetness, drench_capacity, Creature::get_body(), heal(), m_bad, m_good, and mutation_branch::weakness_to_water.

Referenced by suffer().

◆ suffer_while_awake()

void Character::suffer_while_awake ( int  current_stim)
private

Definition at line 300 of file suffer.cpp.

301{
303 ( weight_carried() > 4 * weight_capacity() ) ) {
304 if( has_effect( effect_downed ) ) {
305 add_effect( effect_downed, 1_turns, num_bp, 0 );
306 } else {
307 add_effect( effect_downed, 2_turns, num_bp, 0 );
308 }
309 }
312 }
316 }
317
319 if( one_turn_in( 8_hours ) ) {
321 _( "You're suddenly overcome with the urge to sleep and you pass out." ),
322 _( "<npcname>'s suddenly passes out." ) );
323 fall_asleep( 20_minutes );
324 }
325 }
326
328 if( current_stim > 50 && one_in( to_turns<int>( 30_minutes ) - ( current_stim * 6 ) ) ) {
329 add_effect( effect_shakes, 30_minutes + 1_turns * current_stim );
330 } else if( ( get_kcal_percent() < 0.95f ) &&
331 one_turn_in( 60_minutes - 1_seconds * ( max_stored_kcal() - get_stored_kcal() ) ) ) {
332 add_effect( effect_shakes, 40_minutes );
333 }
334 }
335
336 if( has_trait( trait_MOODSWINGS ) && one_turn_in( 6_hours ) ) {
337 if( rng( 1, 20 ) > 9 ) {
338 // 55% chance
339 add_morale( MORALE_MOODSWING, -100, -500 );
340 } else {
341 // 45% chance
342 add_morale( MORALE_MOODSWING, 100, 500 );
343 }
344 }
345
346 if( has_trait( trait_VOMITOUS ) && one_turn_in( 7_hours ) ) {
347 vomit();
348 }
349
350 if( has_trait( trait_SHOUT1 ) && one_turn_in( 6_hours ) ) {
351 shout();
352 }
353 if( has_trait( trait_SHOUT2 ) && one_turn_in( 4_hours ) ) {
354 shout();
355 }
356 if( has_trait( trait_SHOUT3 ) && one_turn_in( 3_hours ) ) {
357 shout();
358 }
359 if( has_trait( trait_M_SPORES ) && one_turn_in( 4_hours ) ) {
360 spores();
361 }
362 if( has_trait( trait_M_BLOSSOMS ) && one_turn_in( 3_hours ) ) {
363 blossoms();
364 }
365}
void suffer_from_chemimbalance()
Definition: suffer.cpp:367
void suffer_from_schizophrenia()
Definition: suffer.cpp:432
const morale_type MORALE_MOODSWING("morale_moodswing")
static const trait_id trait_JITTERY("JITTERY")
static const trait_id trait_SHOUT1("SHOUT1")
static const trait_id trait_NARCOLEPTIC("NARCOLEPTIC")
static const efftype_id effect_took_thorazine("took_thorazine")
static const trait_id trait_SHOUT2("SHOUT2")
static const trait_id trait_VOMITOUS("VOMITOUS")
static const trait_id trait_DEBUG_STORAGE("DEBUG_STORAGE")
static const trait_id trait_CHEMIMBALANCE("CHEMIMBALANCE")
static const trait_id trait_M_BLOSSOMS("M_BLOSSOMS")
static const trait_id trait_SHOUT3("SHOUT3")
static const trait_id trait_SCHIZOPHRENIC("SCHIZOPHRENIC")
static const trait_id trait_M_SPORES("M_SPORES")
static const trait_id trait_MOODSWINGS("MOODSWINGS")

References _, Creature::add_effect(), add_morale(), Creature::add_msg_player_or_npc(), AEP_SCHIZO, blossoms(), effect_downed, effect_shakes, effect_took_thorazine, fall_asleep(), get_kcal_percent(), get_stored_kcal(), has_artifact_with(), Creature::has_effect(), has_trait(), m_bad, max_stored_kcal(), MORALE_MOODSWING, num_bp, one_in(), one_turn_in(), rng(), shout(), spores(), suffer_from_chemimbalance(), suffer_from_schizophrenia(), trait_CHEMIMBALANCE, trait_DEBUG_STORAGE, trait_JITTERY, trait_M_BLOSSOMS, trait_M_SPORES, trait_MOODSWINGS, trait_NARCOLEPTIC, trait_SCHIZOPHRENIC, trait_SHOUT1, trait_SHOUT2, trait_SHOUT3, trait_VOMITOUS, vomit(), weight_capacity(), and weight_carried().

Referenced by suffer().

◆ suffer_while_underwater()

void Character::suffer_while_underwater ( )
private

Definition at line 250 of file suffer.cpp.

251{
253 oxygen--;
254 }
255 if( oxygen < 12 && worn_with_flag( "REBREATHER" ) ) {
256 oxygen += 12;
257 }
258 if( oxygen <= 5 ) {
260 oxygen += 5;
262 } else {
263 add_msg_if_player( m_bad, _( "You're drowning!" ) );
264 apply_damage( nullptr, bodypart_id( "torso" ), rng( 1, 4 ) );
265 }
266 }
267 if( has_trait( trait_FRESHWATEROSMOSIS ) && !get_map().has_flag_ter( "SALT_WATER", pos() ) &&
269 mod_thirst( -1 );
270 }
271}
static const trait_id trait_FRESHWATEROSMOSIS("FRESHWATEROSMOSIS")
static const trait_id trait_GILLS_CEPH("GILLS_CEPH")
static const trait_id trait_GILLS("GILLS")

References _, Creature::add_msg_if_player(), apply_damage(), bio_gills, get_map(), get_power_level(), get_thirst(), has_bionic(), has_trait(), m_bad, mod_power_level(), mod_thirst(), oxygen, pos(), bionic_data::power_trigger, rng(), trait_FRESHWATEROSMOSIS, trait_GILLS, trait_GILLS_CEPH, turgid, and worn_with_flag().

Referenced by suffer().

◆ suffer_without_sleep()

void Character::suffer_without_sleep ( int  sleep_deprivation)
private

Definition at line 1385 of file suffer.cpp.

1386{
1387 if( has_effect( effect_meth ) ) {
1388 return;
1389 }
1390 // redo as a snippet?
1392 if( one_turn_in( 50_minutes ) ) {
1393 switch( dice( 1, 4 ) ) {
1394 default:
1395 case 1:
1396 add_msg_player_or_npc( m_warning, _( "You tiredly rub your eyes." ),
1397 _( "<npcname> tiredly rubs their eyes." ) );
1398 break;
1399 case 2:
1400 add_msg_player_or_npc( m_warning, _( "You let out a small yawn." ),
1401 _( "<npcname> lets out a small yawn." ) );
1402 break;
1403 case 3:
1404 add_msg_player_or_npc( m_warning, _( "You stretch your back." ),
1405 _( "<npcname> stretches their back." ) );
1406 break;
1407 case 4:
1408 add_msg_player_or_npc( m_warning, _( "You feel mentally tired." ),
1409 _( "<npcname> lets out a huge yawn." ) );
1410 break;
1411 }
1412 }
1413 }
1414 // Minor discomfort
1416 if( one_turn_in( 75_minutes ) ) {
1417 add_msg_if_player( m_warning, _( "You feel lightheaded for a moment." ) );
1418 moves -= 10;
1419 }
1420 if( one_turn_in( 100_minutes ) ) {
1421 add_msg_if_player( m_warning, _( "Your muscles spasm uncomfortably." ) );
1422 mod_pain( 2 );
1423 }
1424 if( !has_effect( effect_visuals ) && one_turn_in( 150_minutes ) ) {
1425 add_msg_if_player( m_warning, _( "Your vision blurs a little." ) );
1426 add_effect( effect_visuals, rng( 1_minutes, 5_minutes ) );
1427 }
1428 }
1429 // Slight disability
1431 if( one_turn_in( 75_minutes ) ) {
1432 add_msg_if_player( m_bad, _( "Your mind lapses into unawareness briefly." ) );
1433 moves -= rng( 20, 80 );
1434 }
1435 if( one_turn_in( 125_minutes ) ) {
1436 add_msg_if_player( m_bad, _( "Your muscles ache in stressfully unpredictable ways." ) );
1437 mod_pain( rng( 2, 10 ) );
1438 }
1439 if( one_turn_in( 5_hours ) ) {
1440 add_msg_if_player( m_bad, _( "You have a distractingly painful headache." ) );
1441 mod_pain( rng( 10, 25 ) );
1442 }
1443 }
1444 // Major disability, high chance of passing out also relevant
1446 if( !has_effect( effect_nausea ) && one_turn_in( 500_minutes ) ) {
1447 add_msg_if_player( m_bad, _( "You feel heartburn and an acid taste in your mouth." ) );
1448 mod_pain( 5 );
1449 add_effect( effect_nausea, rng( 5_minutes, 30_minutes ) );
1450 }
1451 if( one_turn_in( 5_hours ) ) {
1452 add_msg_if_player( m_bad, _( "Your mind is so tired that you feel you can't trust "
1453 "your eyes anymore." ) );
1454 add_effect( effect_hallu, rng( 5_minutes, 60_minutes ) );
1455 }
1456 if( !has_effect( effect_shakes ) && one_turn_in( 425_minutes ) ) {
1457 add_msg_if_player( m_bad, _( "Your muscles spasm uncontrollably, and you have "
1458 "trouble keeping your balance." ) );
1459 add_effect( effect_shakes, 15_minutes );
1460 } else if( has_effect( effect_shakes ) && one_turn_in( 75_seconds ) ) {
1461 moves -= 10;
1462 add_msg_player_or_npc( m_warning, _( "Your shaking legs make you stumble." ),
1463 _( "<npcname> stumbles." ) );
1464 if( !has_effect( effect_downed ) && one_in( 10 ) ) {
1465 add_msg_player_or_npc( m_bad, _( "You fall over!" ), _( "<npcname> falls over!" ) );
1466 add_effect( effect_downed, rng( 3_turns, 10_turns ) );
1467 }
1468 }
1469 }
1470}
static const efftype_id effect_meth("meth")

References _, Creature::add_effect(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), dice(), effect_downed, effect_hallu, effect_meth, effect_nausea, effect_shakes, effect_visuals, harmless, Creature::has_effect(), m_bad, m_warning, major, minor, mod_pain(), Creature::moves, one_in(), one_turn_in(), rng(), serious, and sleep_deprivation.

Referenced by suffer().

◆ swim_speed()

int Character::swim_speed ( ) const

Returns the player's speed for swimming across water tiles.

Strength increases swim speed bonus from PAWS Strength increases swim speed bonus from PAWS_LARGE Strength increases swim speed bonus from swim_fins Strength increases swim speed bonus from WEBBED Swimming increases swim speed Strength increases swim speed Dexterity increases swim speed

Definition at line 803 of file character.cpp.

804{
805 int ret;
806 if( is_mounted() ) {
807 monster *mon = mounted_creature.get();
808 // no difference in swim speed by monster type yet.
809 // TODO: difference in swim speed by monster type.
810 // No monsters are currently mountable and can swim, though mods may allow this.
811 if( mon->swims() ) {
812 ret = 25;
813 ret += get_weight() / 120_gram - 50 * mon->get_size();
814 return ret;
815 }
816 }
817 const auto usable = exclusive_flag_coverage( "ALLOWS_NATURAL_ATTACKS" );
818 float hand_bonus_mult = ( usable.test( bp_hand_l ) ? 0.5f : 0.0f ) +
819 ( usable.test( bp_hand_r ) ? 0.5f : 0.0f );
820
821 // base swim speed.
822 ret = ( 440 * mutation_value( "movecost_swim_modifier" ) ) + weight_carried() /
823 ( 60_gram / mutation_value( "movecost_swim_modifier" ) ) - 50 * get_skill_level( skill_swimming );
824 /** @EFFECT_STR increases swim speed bonus from PAWS */
825 if( has_trait( trait_PAWS ) ) {
826 ret -= hand_bonus_mult * ( 20 + str_cur * 3 );
827 }
828 /** @EFFECT_STR increases swim speed bonus from PAWS_LARGE */
829 if( has_trait( trait_PAWS_LARGE ) ) {
830 ret -= hand_bonus_mult * ( 20 + str_cur * 4 );
831 }
832 /** @EFFECT_STR increases swim speed bonus from swim_fins */
833 if( worn_with_flag( "FIN", bodypart_id( "foot_l" ) ) ||
834 worn_with_flag( "FIN", bodypart_id( "foot_r" ) ) ) {
835 if( worn_with_flag( "FIN", bodypart_id( "foot_l" ) ) &&
836 worn_with_flag( "FIN", bodypart_id( "foot_r" ) ) ) {
837 ret -= ( 15 * str_cur );
838 } else {
839 ret -= ( 15 * str_cur ) / 2;
840 }
841 }
842 /** @EFFECT_STR increases swim speed bonus from WEBBED */
843 if( has_trait( trait_WEBBED ) ) {
844 ret -= hand_bonus_mult * ( 60 + str_cur * 5 );
845 }
846 /** @EFFECT_SWIMMING increases swim speed */
847 ret += ( 50 - get_skill_level( skill_swimming ) * 2 ) * ( ( encumb( bp_leg_l ) + encumb(
848 bp_leg_r ) ) / 10 );
849 ret += ( 80 - get_skill_level( skill_swimming ) * 3 ) * ( encumb( bp_torso ) / 10 );
850 if( get_skill_level( skill_swimming ) < 10 ) {
851 for( auto &i : worn ) {
852 ret += i.volume() / 125_ml * ( 10 - get_skill_level( skill_swimming ) );
853 }
854 }
855 /** @EFFECT_STR increases swim speed */
856
857 /** @EFFECT_DEX increases swim speed */
858 ret -= str_cur * 6 + dex_cur * 4;
859 if( worn_with_flag( "FLOTATION" ) ) {
860 ret = std::min( ret, 400 );
861 ret = std::max( ret, 200 );
862 }
863 // If (ret > 500), we can not swim; so do not apply the underwater bonus.
864 if( is_underwater() && ret < 500 ) {
865 ret -= 50;
866 }
867
868 // Running movement mode while swimming means faster swim style, like crawlstroke
869 if( move_mode == CMM_RUN ) {
870 ret -= 80;
871 }
872 // Crouching movement mode while swimming means slower swim style, like breaststroke
873 if( move_mode == CMM_CROUCH ) {
874 ret += 50;
875 }
876
877 if( ret < 30 ) {
878 ret = 30;
879 }
880 return ret;
881}
static const skill_id skill_swimming("swimming")
static const trait_id trait_WEBBED("WEBBED")
static const trait_id trait_PAWS_LARGE("PAWS_LARGE")
static const trait_id trait_PAWS("PAWS")
bool swims() const
Definition: monster.cpp:955

References bp_hand_l, bp_hand_r, bp_leg_l, bp_leg_r, bp_torso, CMM_CROUCH, CMM_RUN, dex_cur, encumb(), exclusive_flag_coverage(), monster::get_size(), get_skill_level(), get_weight(), has_trait(), is_mounted(), Creature::is_underwater(), mounted_creature, move_mode, mutation_value(), cata::hash64_detail::ret, skill_swimming, str_cur, monster::swims(), trait_PAWS, trait_PAWS_LARGE, trait_WEBBED, weight_carried(), worn, and worn_with_flag().

Referenced by avatar_action::move(), avatar_action::swim(), and game::vertical_move().

◆ switch_mutations()

void Character::switch_mutations ( const trait_id switched,
const trait_id target,
bool  start_powered 
)

Unset switched mutation and set target mutation instead.

Definition at line 184 of file mutation.cpp.

186{
187 unset_mutation( switched );
188 mutation_loss_effect( switched );
189
190 set_mutation( target );
191 my_mutations[target].powered = start_powered;
192 mutation_effect( target );
193}

References mutation_effect(), mutation_loss_effect(), my_mutations, set_mutation(), and unset_mutation().

Referenced by activate_mutation(), and deactivate_mutation().

◆ symbol()

const std::string & Character::symbol ( ) const
overridevirtual

Implements Creature.

Definition at line 526 of file character.cpp.

527{
528 static const std::string character_symbol( "@" );
529 return character_symbol;
530}

Referenced by anonymous_namespace{animation.cpp}::draw_hit_player_curses(), and avatar::memorize_symbol().

◆ symbol_color()

nc_color Character::symbol_color ( ) const
overridevirtual

Implements Creature.

Definition at line 6004 of file character.cpp.

6005{
6006 nc_color basic = basic_symbol_color();
6007
6008 if( has_effect( effect_downed ) ) {
6009 return hilite( basic );
6010 } else if( has_effect( effect_grabbed ) ) {
6011 return cyan_background( basic );
6012 }
6013
6014 const auto &fields = get_map().field_at( pos() );
6015
6016 // Priority: electricity, fire, acid, gases
6017 bool has_elec = false;
6018 bool has_fire = false;
6019 bool has_acid = false;
6020 bool has_fume = false;
6021 for( const auto &field : fields ) {
6022 has_elec = field.first.obj().has_elec;
6023 if( has_elec ) {
6024 return hilite( basic );
6025 }
6026 has_fire = field.first.obj().has_fire;
6027 has_acid = field.first.obj().has_acid;
6028 has_fume = field.first.obj().has_fume;
6029 }
6030 if( has_fire ) {
6031 return red_background( basic );
6032 }
6033 if( has_acid ) {
6034 return green_background( basic );
6035 }
6036 if( has_fume ) {
6037 return white_background( basic );
6038 }
6039 if( in_sleep_state() ) {
6040 return hilite( basic );
6041 }
6042 return basic;
6043}
nc_color basic_symbol_color() const override
Definition: character.cpp:5974
A variable sized collection of field entries on a given map square.
Definition: field.h:131
const field & field_at(const tripoint &p) const
Get the fields that are here.
Definition: map.cpp:5302
nc_color white_background(const nc_color &c)
Definition: color.cpp:521
nc_color green_background(const nc_color &c)
Definition: color.cpp:527
nc_color red_background(const nc_color &c)
Definition: color.cpp:515
nc_color cyan_background(const nc_color &c)
Definition: color.cpp:545
nc_color hilite(const nc_color &c)
Definition: color.cpp:509

References basic_symbol_color(), cyan_background(), effect_downed, effect_grabbed, map::field_at(), get_map(), green_background(), Creature::has_effect(), has_fire(), hilite(), in_sleep_state(), pos(), red_background(), and white_background().

Referenced by overmap_ui::draw_ascii(), anonymous_namespace{animation.cpp}::draw_hit_player_curses(), and game::list_monsters().

◆ takeoff()

bool Character::takeoff ( item it,
std::list< item > *  res = nullptr 
)

Take off an item.

May start an activity.

Parameters
itItem to take off
[out]resIf set, moves resulting item into the list.
Returns
true on success

Definition at line 3012 of file character.cpp.

3013{
3014 const auto ret = can_takeoff( it, res );
3015 if( !ret.success() ) {
3016 add_msg( m_info, "%s", ret.c_str() );
3017 return false;
3018 }
3019
3020 auto iter = std::find_if( worn.begin(), worn.end(), [ &it ]( const item & wit ) {
3021 return &it == &wit;
3022 } );
3023
3024 if( res == nullptr ) {
3026 if( is_npc() || query_yn( _( "No room in inventory for your %s. Drop it?" ),
3027 colorize( it.tname(), it.color_in_inventory() ) ) ) {
3028 item_location loc( *this, &it );
3029 drop( loc, pos() );
3030 return true; // the drop activity ends up taking off the item anyway so shouldn't try to do it again here
3031 } else {
3032 return false;
3033 }
3034 }
3035 iter->on_takeoff( *this );
3037 } else {
3038 iter->on_takeoff( *this );
3039 res->push_back( it );
3040 }
3041
3042 add_msg_player_or_npc( _( "You take off your %s." ),
3043 _( "<npcname> takes off their %s." ),
3044 it.tname() );
3045
3046 // TODO: Make this variable
3047 mod_moves( -250 );
3048 worn.erase( iter );
3049
3052
3053 return true;
3054}
units::volume volume_capacity_reduced_by(const units::volume &mod, const excluded_stacks &without={}) const
Definition: character.cpp:2644
nc_color color_in_inventory() const
Returns the color of the item depending on usefulness for the player character, e....
Definition: item.cpp:4119
units::volume get_storage() const
Returns the storage amount (islot_armor::storage) that this item provides when worn.
Definition: item.cpp:5737

References _, inventory::add_item_keep_invlet(), add_msg(), Creature::add_msg_player_or_npc(), can_takeoff(), item::color_in_inventory(), colorize(), drop(), item::get_storage(), inv, Creature::is_npc(), m_info, Creature::mod_moves(), pos(), query_yn(), recalc_sight_limits(), reset_encumbrance(), cata::hash64_detail::ret, item::tname(), item::volume(), volume_capacity_reduced_by(), volume_carried(), and worn.

Referenced by npc::adjust_worn(), pickup::obtain_and_tokenize_items(), examine_item_menu::run(), show_armor_layers_ui(), takeoff(), and npc::wear_if_wanted().

◆ temp_corrected_by_climate_control()

int Character::temp_corrected_by_climate_control ( int  temperature) const

Value of the body temperature corrected by climate control.

Definition at line 9515 of file character.cpp.

9516{
9517 const int variation = int( BODYTEMP_NORM * 0.5 );
9518 if( temperature < BODYTEMP_SCORCHING + variation &&
9519 temperature > BODYTEMP_FREEZING - variation ) {
9522 } else if( temperature > BODYTEMP_VERY_HOT ) {
9524 } else if( temperature > BODYTEMP_HOT ) {
9526 } else if( temperature < BODYTEMP_FREEZING ) {
9528 } else if( temperature < BODYTEMP_VERY_COLD ) {
9530 } else if( temperature < BODYTEMP_COLD ) {
9532 }
9533 }
9534 return temperature;
9535}

References BODYTEMP_COLD, BODYTEMP_FREEZING, BODYTEMP_HOT, BODYTEMP_NORM, BODYTEMP_SCORCHING, BODYTEMP_VERY_COLD, and BODYTEMP_VERY_HOT.

Referenced by update_bodytemp().

◆ temp_equalizer()

void Character::temp_equalizer ( const bodypart_id bp1,
const bodypart_id bp2 
)

Equalizes heat between body parts.

Definition at line 5674 of file character.cpp.

5675{
5676 // Body heat is moved around.
5677 // If bp1 is warmer, it will lose heat
5678 int diff = static_cast<int>( ( temp_cur[bp2->token] - temp_cur[bp1->token] ) * 0.001 );
5679 temp_cur[bp1->token] += diff;
5680 temp_cur[bp2->token] -= diff;
5681}

References temp_cur.

Referenced by update_bodytemp().

◆ throw_range()

int Character::throw_range ( const item it) const

Maximum thrown range with a given item, taking all active effects into account.

Strength determines maximum weight that can be thrown Strength increases throwing range, vs item weight (high or low) Strength caps throwing range Throw caps throwing range

Definition at line 6162 of file character.cpp.

6163{
6164 if( it.is_null() ) {
6165 return -1;
6166 }
6167
6168 item tmp = it;
6169
6170 if( tmp.count_by_charges() && tmp.charges > 1 ) {
6171 tmp.charges = 1;
6172 }
6173
6174 /** @EFFECT_STR determines maximum weight that can be thrown */
6175 if( ( tmp.weight() / 113_gram ) > static_cast<int>( str_cur * 15 ) ) {
6176 return 0;
6177 }
6178 // Increases as weight decreases until 150 g, then decreases again
6179 /** @EFFECT_STR increases throwing range, vs item weight (high or low) */
6180 int str_override = str_cur;
6181 if( is_mounted() ) {
6182 auto mons = mounted_creature.get();
6183 str_override = mons->mech_str_addition() != 0 ? mons->mech_str_addition() : str_cur;
6184 }
6185 int ret = ( str_override * 10 ) / ( tmp.weight() >= 150_gram ? tmp.weight() / 113_gram : 10 -
6186 static_cast<int>(
6187 tmp.weight() / 15_gram ) );
6188 ret -= tmp.volume() / 1_liter;
6189 static const std::set<material_id> affected_materials = { material_id( "iron" ), material_id( "steel" ) };
6190 if( has_active_bionic( bio_railgun ) && tmp.made_of_any( affected_materials ) ) {
6191 ret *= 2;
6192 }
6193 if( ret < 1 ) {
6194 return 1;
6195 }
6196 // Cap at double our strength + skill
6197 /** @EFFECT_STR caps throwing range */
6198
6199 /** @EFFECT_THROW caps throwing range */
6200 if( ret > str_override * 3 + get_skill_level( skill_throw ) ) {
6201 return str_override * 3 + get_skill_level( skill_throw );
6202 }
6203
6204 return ret;
6205}
static const bionic_id bio_railgun("bio_railgun")
static const skill_id skill_throw("throw")

References bio_railgun, item::charges, item::count_by_charges(), get_skill_level(), has_active_bionic(), is_mounted(), item::is_null(), item::made_of_any(), mounted_creature, cata::hash64_detail::ret, skill_throw, str_cur, item::volume(), and item::weight().

Referenced by npc::alt_attack(), target_handler::mode_throw(), and avatar_action::plthrow().

◆ toggle_trait()

void Character::toggle_trait ( const trait_id trait_)

Toggles a trait on the player and in their mutation list.

Definition at line 127 of file mutation.cpp.

128{
129 // Take copy of argument because it might be a reference into a container
130 // we're about to erase from.
131 // NOLINTNEXTLINE(performance-unnecessary-copy-initialization)
132 const trait_id trait = trait_;
133 const auto titer = my_traits.find( trait );
134 const auto miter = my_mutations.find( trait );
135 // These shouldn't be inlined, otherwise the sync check uses invalid iterators
136 bool no_trait = titer == my_traits.end();
137 bool no_mutation = miter == my_mutations.end();
138 if( no_trait ) {
139 my_traits.insert( trait );
140 } else {
141 my_traits.erase( titer );
142 }
143 if( no_trait != no_mutation ) {
144 debugmsg( "my_traits and my_mutations were out of sync for %s\n", trait.str() );
145 return;
146 }
147 if( no_mutation ) {
148 set_mutation( trait );
149 } else {
150 unset_mutation( trait );
151 }
152}

References debugmsg, my_mutations, my_traits, set_mutation(), string_id< T >::str(), and unset_mutation().

Referenced by newcharacter::add_traits(), clear_mutations(), avatar::create(), tutorial_game::init(), wish_mutate_callback::key(), avatar::randomize(), npc::randomize(), reset_scenario(), set_profession(), set_traits(), and gun_actor::shoot().

◆ unarmed_attack()

bool Character::unarmed_attack ( ) const

True if unarmed or wielding a weapon with the UNARMED_WEAPON flag.

Definition at line 153 of file melee.cpp.

154{
155 const item &weap = used_weapon();
156 return weap.is_null() || weap.has_flag( "UNARMED_WEAPON" );
157}

References item::has_flag(), item::is_null(), and used_weapon().

Referenced by mattack::copbot(), has_weapon(), conditional_t< T >::set_can_stow_weapon(), and conditional_t< T >::set_has_weapon().

◆ uncanny_dodge()

bool Character::uncanny_dodge ( )
overridevirtual

Handles the uncanny dodge bionic and effects, returns true if the creature successfully dodges.

Reimplemented from Creature.

Definition at line 10615 of file character.cpp.

10616{
10617 return character_funcs::try_uncanny_dodge( *this );
10618}
bool try_uncanny_dodge(Character &who)
Try to execute an uncanny dodge bionic ability.

References character_funcs::try_uncanny_dodge().

Referenced by mattack::grab(), and mattack::science().

◆ unimpaired_range()

int Character::unimpaired_range ( ) const

Returns the player maximum vision range factoring in mutations, diseases, and other effects.

Definition at line 616 of file character.cpp.

617{
618 return std::min( sight_max, 60 );
619}

References sight_max.

Referenced by sees().

◆ uninstall_bionic() [1/2]

bool Character::uninstall_bionic ( const bionic target_cbm,
monster installer,
player patient,
float  adjusted_skill 
)

Used by monster to perform surgery.

Definition at line 2078 of file bionics.cpp.

2080{
2081 if( installer.ammo[itype_anesthetic] <= 0 ) {
2082 if( g->u.sees( installer ) ) {
2083 add_msg( _( "The %s's anesthesia kit looks empty." ), installer.name() );
2084 }
2085 return false;
2086 }
2087
2088 const itype_id itemtype = target_cbm.info().itype();
2089 int difficulty = itemtype.is_valid() ? itemtype->bionic->difficulty : BIONIC_NOITEM_DIFFICULTY;
2090 int chance_of_success = bionic_manip_cos( adjusted_skill, difficulty + 2 );
2091 int success = chance_of_success - rng( 1, 100 );
2092
2093 const time_duration duration = difficulty * 20_minutes;
2094 // don't stack up the effect
2095 if( !installer.has_effect( effect_operating ) ) {
2096 installer.add_effect( effect_operating, duration + 5_turns );
2097 }
2098
2099 if( patient.is_player() ) {
2100 add_msg( m_bad,
2101 _( "You feel a tiny pricking sensation in your right arm, and lose all sensation before abruptly blacking out." ) );
2102 } else if( g->u.sees( installer ) ) {
2103 add_msg( m_bad,
2104 _( "The %1$s gently inserts a syringe into %2$s's arm and starts injecting something while holding them down." ),
2105 installer.name(), patient.disp_name() );
2106 }
2107
2108 installer.ammo[itype_anesthetic] -= 1;
2109
2110 patient.add_effect( effect_narcosis, duration );
2111 patient.add_effect( effect_sleep, duration );
2112
2113 if( patient.is_player() ) {
2114 add_msg( _( "You fall asleep and %1$s starts operating." ), installer.disp_name() );
2115 } else if( g->u.sees( patient ) ) {
2116 add_msg( _( "%1$s falls asleep and %2$s starts operating." ), patient.disp_name(),
2117 installer.disp_name() );
2118 }
2119
2120 if( success > 0 ) {
2121
2122 if( patient.is_player() ) {
2123 add_msg( m_neutral, _( "Your parts are jiggled back into their familiar places." ) );
2124 add_msg( m_mixed, _( "Successfully removed %s." ), target_cbm.info().name );
2125 } else if( patient.is_npc() && g->u.sees( patient ) ) {
2126 add_msg( m_neutral, _( "%s's parts are jiggled back into their familiar places." ),
2127 patient.disp_name() );
2128 add_msg( m_mixed, _( "Successfully removed %s." ), target_cbm.info().name );
2129 }
2130
2131 // remove power bank provided by bionic
2132 patient.mod_max_power_level( -target_cbm.info().capacity );
2133 patient.remove_bionic( target_cbm.id );
2134 const itype_id iid = itemtype.is_valid() ? itemtype : itype_burnt_out_bionic;
2136 cbm.faults.emplace( fault_bionic_nonsterile );
2137 get_map().add_item( patient.pos(), cbm );
2138 } else {
2139 bionics_uninstall_failure( installer, patient, difficulty, success, adjusted_skill );
2140 }
2141
2142 return false;
2143}
static const efftype_id effect_sleep("sleep")
static const efftype_id effect_operating("operating")
static const itype_id itype_anesthetic("anesthetic")
std::map< itype_id, int > ammo
Definition: monster.h:511
std::string disp_name(bool possessive=false, bool capitalize_first=false) const override
Definition: monster.cpp:537
bool is_npc() const override
Definition: player.h:103

References _, Creature::add_effect(), monster::add_effect(), map::add_item(), add_msg(), monster::ammo, itype::bionic, bionic_manip_cos(), BIONIC_NOITEM_DIFFICULTY, bionics_uninstall_failure(), bionic_data::capacity, disp_name(), monster::disp_name(), effect_narcosis, effect_operating, effect_sleep, fault_bionic_nonsterile, item::faults, g, get_map(), Creature::has_effect(), bionic::id, bionic::info(), player::is_npc(), player::is_player(), string_id< T >::is_valid(), bionic_data::itype(), itype_anesthetic, itype_burnt_out_bionic, m_bad, m_mixed, m_neutral, mod_max_power_level(), bionic_data::name, monster::name(), pos(), remove_bionic(), rng(), calendar::start_of_cataclysm, and behavior::success.

◆ uninstall_bionic() [2/2]

bool Character::uninstall_bionic ( const bionic_id b_id,
player installer,
bool  autodoc = false,
int  skill_level = -1 
)

Initialize all the values needed to start the operation player_activity.

Definition at line 1974 of file bionics.cpp.

1976{
1977 // If malfunctioning bionics doesn't have associated item it gets predefined difficulty
1978 int difficulty = BIONIC_NOITEM_DIFFICULTY;
1979 if( b_id->itype().is_valid() ) {
1980 const itype *type = &*b_id->itype();
1981 if( type->bionic ) {
1982 difficulty = type->bionic->difficulty;
1983 }
1984 }
1985
1986 // removal of bionics adds +2 difficulty over installation
1987 float adjusted_skill;
1988 int pl_skill;
1989 if( autodoc ) {
1990 adjusted_skill = installer.bionics_adjusted_skill( skill_firstaid,
1993 skill_level );
1994 pl_skill = installer.bionics_pl_skill( skill_firstaid,
1997 skill_level );
1998 } else {
1999 adjusted_skill = installer.bionics_adjusted_skill( skill_electronics,
2002 skill_level );
2003 pl_skill = installer.bionics_pl_skill( skill_electronics,
2006 skill_level );
2007 }
2008
2009 int chance_of_success = bionic_manip_cos( adjusted_skill, difficulty + 2 );
2010
2011 // Surgery is imminent, retract claws or blade if active
2012 for( bionic &bio : *installer.my_bionics ) {
2013 if( bio.powered && bio.info().has_flag( flag_BIONIC_WEAPON ) ) {
2014 installer.deactivate_bionic( bio );
2015 }
2016 }
2017
2018 int success = chance_of_success - rng( 1, 100 );
2019 if( installer.has_trait( trait_DEBUG_BIONICS ) ) {
2020 perform_uninstall( b_id, difficulty, success, b_id->capacity, pl_skill );
2021 return true;
2022 }
2023 assign_activity( ACT_OPERATION, to_moves<int>( difficulty * 20_minutes ) );
2024
2025 activity.values.push_back( difficulty );
2026 activity.values.push_back( success );
2027 activity.values.push_back( units::to_kilojoule( b_id->capacity ) );
2028 activity.values.push_back( pl_skill );
2029 activity.str_values.push_back( "uninstall" );
2030 activity.str_values.push_back( b_id.str() );
2031 activity.str_values.push_back( "" ); // installer_name is unused for uninstall
2032 if( autodoc ) {
2033 activity.str_values.push_back( "true" );
2034 } else {
2035 activity.str_values.push_back( "false" );
2036 }
2037 for( const std::pair<const bodypart_str_id, int> &elem : b_id->occupied_bodyparts ) {
2038 add_effect( effect_under_op, difficulty * 20_minutes, elem.first->token, difficulty );
2039 }
2040
2041 return true;
2042}
void perform_uninstall(bionic_id bid, int difficulty, int success, const units::energy &power_lvl, int pl_skill)
Succes or failure of removal happens here.
Definition: bionics.cpp:2044

References ACT_OPERATION, activity, Creature::add_effect(), assign_activity(), iexamine::autodoc(), bionic_manip_cos(), BIONIC_NOITEM_DIFFICULTY, bionics_adjusted_skill(), bionics_pl_skill(), bionic_data::capacity, deactivate_bionic(), effect_under_op, flag_BIONIC_WEAPON, bionic_data::has_flag(), has_trait(), bionic::info(), string_id< T >::is_valid(), bionic_data::itype(), my_bionics, bionic_data::occupied_bodyparts, perform_uninstall(), bionic::powered, rng(), skill_computer, skill_electronics, skill_firstaid, skill_mechanics, string_id< T >::str(), player_activity::str_values, behavior::success, units::to_kilojoule(), trait_DEBUG_BIONICS, type, and player_activity::values.

Referenced by iexamine::autodoc().

◆ unset_mutation()

void Character::unset_mutation ( const trait_id trait_)

Definition at line 167 of file mutation.cpp.

168{
169 // Take copy of argument because it might be a reference into a container
170 // we're about to erase from.
171 // NOLINTNEXTLINE(performance-unnecessary-copy-initialization)
172 const trait_id trait = trait_;
173 const auto iter = my_mutations.find( trait );
174 if( iter == my_mutations.end() ) {
175 return;
176 }
177 my_mutations.erase( iter );
179 mutation_loss_effect( trait );
182}

References mutation_loss_effect(), my_mutations, rebuild_mutation_cache(), recalc_sight_limits(), and reset_encumbrance().

Referenced by clear_mutations(), wish_mutate_callback::key(), marloss_common(), mutate_towards(), iuse::mycus(), remove_mutation(), talk_effect_fun_t::set_remove_trait(), switch_mutations(), test_crossing_threshold(), toggle_trait(), and try_reject_mutagen().

◆ unwield()

bool Character::unwield ( )

Removes currently wielded item (if any)

Definition at line 3104 of file character.cpp.

3105{
3106 if( weapon.is_null() ) {
3107 return true;
3108 }
3109
3110 if( !can_unwield( weapon ).success() ) {
3111 return false;
3112 }
3113
3114 const std::string query = string_format( _( "Stop wielding %s?" ), weapon.tname() );
3115
3116 if( !dispose_item( item_location( *this, &weapon ), query ) ) {
3117 return false;
3118 }
3119
3120 inv.unsort();
3121
3122 return true;
3123}

References _, can_unwield(), dispose_item(), inv, item::is_null(), string_format(), behavior::success, item::tname(), inventory::unsort(), and weapon.

Referenced by character_funcs::try_wield_contents(), avatar::wield(), and avatar_action::wield().

◆ update_body() [1/2]

void Character::update_body ( )

Updates all "biology" by one turn.

Should be called once every turn.

Definition at line 4653 of file character.cpp.

4654{
4656}
void update_body()
Updates all "biology" by one turn.
Definition: character.cpp:4653

References calendar::turn, and update_body().

Referenced by game::do_turn(), npc::npc_update_body(), npc::on_load(), and update_body().

◆ update_body() [2/2]

void Character::update_body ( const time_point from,
const time_point to 
)

Updates all "biology" as if time between from and to passed.

Definition at line 4658 of file character.cpp.

4659{
4660 if( !is_npc() ) {
4661 update_stamina( to_turns<int>( to - from ) );
4662 }
4663 update_stomach( from, to );
4665 if( ticks_between( from, to, 3_minutes ) > 0 ) {
4666 magic->update_mana( *this->as_player(), to_turns<double>( 3_minutes ) );
4667 }
4668 const int five_mins = ticks_between( from, to, 5_minutes );
4669 if( five_mins > 0 ) {
4671 update_needs( five_mins );
4672 regen( five_mins );
4673 // Note: mend ticks once per 5 minutes, but wants rate in TURNS, not 5 minute intervals
4674 // TODO: change @ref med to take time_duration
4675 mend( five_mins * to_turns<int>( 5_minutes ) );
4676 }
4677 if( ticks_between( from, to, 24_hours ) > 0 ) {
4679 }
4680
4681 const int thirty_mins = ticks_between( from, to, 30_minutes );
4682 if( thirty_mins > 0 ) {
4683 // Radiation kills health even at low doses
4685 }
4686
4687 for( const auto &v : vitamin::all() ) {
4688 const time_duration rate = vitamin_rate( v.first );
4689 if( rate > 0_turns ) {
4690 int qty = ticks_between( from, to, rate );
4691 if( qty > 0 ) {
4692 vitamin_mod( v.first, 0 - qty );
4693 }
4694
4695 } else if( rate < 0_turns ) {
4696 // mutations can result in vitamins being generated (but never accumulated)
4697 int qty = ticks_between( from, to, -rate );
4698 if( qty > 0 ) {
4699 vitamin_mod( v.first, qty );
4700 }
4701 }
4702 }
4703
4704 do_skill_rust();
4705}
int ticks_between(const time_point &from, const time_point &to, const time_duration &tick_length)
Definition: character.cpp:4646
static const trait_id trait_RADIOGENIC("RADIOGENIC")
void check_needs_extremes()
Kills the player if too hungry, stimmed up etc., forces tired player to sleep and prints warnings.
Definition: character.cpp:4960
void do_skill_rust()
Definition: character.cpp:3564
void update_needs(int rate_multiplier)
Increases hunger, thirst, fatigue and stimulants wearing off.
Definition: character.cpp:4764
virtual void update_health(int external_modifiers=0)
Handles health fluctuations over time.
Definition: character.cpp:4609
void regen(int rate_multiplier)
Handles passive regeneration of pain and maybe hp.
Definition: character.cpp:4536
void update_stomach(const time_point &from, const time_point &to)
Updates the stomach to give accurate hunger messages.
Definition: character.cpp:4721
void mend(int rate_multiplier)
Handles the chance for broken limbs to spontaneously heal to 1 HP.
Definition: suffer.cpp:1607
time_duration vitamin_rate(const vitamin_id &vit) const
Get vitamin usage rate (minutes per unit) accounting for bionics, mutations and effects.
void enforce_minimum_healing()
Definition: character.cpp:4599
void update_stamina(int turns)
Regenerates stamina.
Definition: character.cpp:7128

References vitamin::all(), Creature::as_player(), check_needs_extremes(), do_skill_rust(), enforce_minimum_healing(), get_rad(), has_trait(), Creature::is_npc(), magic, mend(), recalculate_enchantment_cache(), regen(), ticks_between(), trait_RADIOGENIC, update_health(), update_needs(), update_stamina(), update_stomach(), vitamin_mod(), and vitamin_rate().

◆ update_bodytemp()

void Character::update_bodytemp ( const map m,
const weather_manager weather 
)

Maintains body temperature.

Calculations that affect all body parts equally go here, not in the loop

Source : http://www.atc.army.mil/weather/windchill.pdf

Temperature and wind chill are main factors, mitigated by clothing warmth. Each 10 warmth protects against 2C of cold.

1200 turns in low risk, + 3 tics 450 turns in moderate risk, + 8 tics 50 turns in high risk, +72 tics

Let's say frostnip @ 1800 tics, frostbite @ 3600 tics

Chunked into 8 parts (http://imgur.com/xlTPmJF)

– 2 hour risk – Between 30F and 10F Between 10F and -5F, less than 20mph, -4x + 3y - 20 > 0, x : F, y : mph – 45 minute risk – Between 10F and -5F, less than 20mph, -4x + 3y - 20 < 0, x : F, y : mph Between 10F and -5F, greater than 20mph Less than -5F, less than 10 mph Less than -5F, more than 10 mph, -4x + 3y - 170 > 0, x : F, y : mph – 5 minute risk – Less than -5F, more than 10 mph, -4x + 3y - 170 < 0, x : F, y : mph Less than -35F, more than 10 mp

Definition at line 5179 of file character.cpp.

5180{
5181 if( has_trait( trait_DEBUG_NOTEMP ) ) {
5182 temp_cur.fill( BODYTEMP_NORM );
5183 temp_conv.fill( BODYTEMP_NORM );
5184 return;
5185 }
5186 /* Cache calls to g->get_temperature( player position ), used in several places in function */
5187 const auto player_local_temp = weather.get_temperature( pos() );
5188 // NOTE : visit weather.h for some details on the numbers used
5189 // In Celsius / 100
5190 int Ctemperature = static_cast<int>( 100 * units::fahrenheit_to_celsius( player_local_temp ) );
5191 const w_point &weather_point = get_weather().get_precise();
5192 int vehwindspeed = 0;
5193 const optional_vpart_position vp = m.veh_at( pos() );
5194 if( vp ) {
5195 vehwindspeed = std::abs( vp->vehicle().velocity / 100 ); // vehicle velocity in mph
5196 }
5197 const oter_id &cur_om_ter = overmap_buffer.ter( global_omt_location() );
5198 bool sheltered = weather::is_sheltered( m, pos() );
5199 double total_windpower = get_local_windpower( weather.windspeed + vehwindspeed, cur_om_ter,
5200 pos(),
5201 weather.winddirection, sheltered );
5202 int air_humidity = get_local_humidity( weather_point.humidity, weather.weather_id,
5203 sheltered );
5204 // Let's cache this not to check it num_bp times
5205 const bool has_bark = has_trait( trait_BARK );
5206 const bool has_heatsink = has_bionic( bio_heatsink ) || is_wearing( itype_rm13_armor_on ) ||
5208 const bool has_climate_control = in_climate_control();
5209 const bool use_floor_warmth = can_use_floor_warmth();
5210 const cata::optional<vpart_reference> boardable = vp.part_with_feature( "BOARDABLE", true );
5211 // In bodytemp units
5212 const int ambient_norm = 1900 - BODYTEMP_NORM;
5213
5214 /**
5215 * Calculations that affect all body parts equally go here, not in the loop
5216 */
5217 const int sunlight_warmth = weather::is_in_sunlight( m, pos(), weather.weather_id )
5218 ? ( weather.weather_id->sun_intensity == sun_intensity_type::high ? 1000 : 500 )
5219 : 0;
5220 const int best_fire = get_heat_radiation( pos(), true );
5221 const bool pyromania = has_trait( trait_PYROMANIA );
5222
5223 const int lying_warmth = use_floor_warmth ? floor_warmth( pos() ) : 0;
5224 const int water_temperature_raw =
5225 100 * units::fahrenheit_to_celsius( weather.get_water_temperature( pos() ) );
5226 // Rescale so that 0C is 0 (FREEZING) and 30C is 5k (NORM).
5227 const int water_temperature = water_temperature_raw * 5 / 3;
5228
5229 // Correction of body temperature due to traits and mutations
5230 // Lower heat is applied always
5231 const int mutation_heat_low = bodytemp_modifier_traits( true );
5232 const int mutation_heat_high = bodytemp_modifier_traits( false );
5233 // Difference between high and low is the "safe" heat - one we only apply if it's beneficial
5234 const int mutation_heat_bonus = mutation_heat_high - mutation_heat_low;
5235
5236 // Note: this is included in @ref weather::get_temperature(), so don't add to bodytemp!
5237 const int h_radiation = get_heat_radiation( pos(), false );
5238
5239 // If you're standing in water, air temperature is replaced by water temperature. No wind.
5240 const ter_id ter_at_pos = m.ter( pos() );
5241 const bool submerged = !in_vehicle && ter_at_pos->has_flag( TFLAG_DEEP_WATER );
5242 const bool submerged_low = !in_vehicle && ( submerged || ter_at_pos->has_flag( TFLAG_SWIMMABLE ) );
5243
5244 std::map<bodypart_id, std::vector<const item *>> clothing_map;
5245 std::map<bodypart_id, std::vector<const item *>> bonus_clothing_map;
5246 for( const bodypart_id &bp : get_all_body_parts() ) {
5247 clothing_map.emplace( bp, std::vector<const item *>() );
5248 bonus_clothing_map.emplace( bp, std::vector<const item *>() );
5249 // HACK: we're using temp_conv here to temporarily save
5250 // temperature values from before equalization.
5251 temp_conv[bp->token] = temp_cur[bp->token];
5252 }
5253
5254 // EQUALIZATION
5255 // We run it outside the loop because we can and so we should
5256 // Also, it makes bonus heat application more stable
5257 // TODO: Affect future convection temperature instead (might require adding back to loop)
5263
5266
5269
5270 for( const item &it : worn ) {
5271 // TODO: Port body part set id changes
5272 const body_part_set &covered = it.get_covered_body_parts();
5273 for( size_t i = 0; i < num_bp; i++ ) {
5274 body_part token = static_cast<body_part>( i );
5275 if( covered.test( token ) ) {
5276 clothing_map[convert_bp( token )].emplace_back( &it );
5277 }
5278 if( it.has_flag( flag_HOOD ) ) {
5279 bonus_clothing_map[body_part_head].emplace_back( &it );
5280 }
5281 if( it.has_flag( flag_COLLAR ) ) {
5282 bonus_clothing_map[body_part_mouth].emplace_back( &it );
5283 }
5284 if( it.has_flag( flag_POCKETS ) ) {
5285 bonus_clothing_map[body_part_hand_l].emplace_back( &it );
5286 bonus_clothing_map[body_part_hand_r].emplace_back( &it );
5287 }
5288 }
5289 }
5290 // If player is wielding something large, pockets are not usable
5291 if( weapon.volume() >= 500_ml ) {
5292 bonus_clothing_map[body_part_hand_l].clear();
5293 bonus_clothing_map[body_part_hand_r].clear();
5294 }
5295 // If player's head is encumbered, hood can't be put up
5296 if( encumb( body_part_head->token ) >= 10 ) {
5297 bonus_clothing_map[body_part_head].clear();
5298 }
5299 // Similar for mouth
5300 if( encumb( body_part_mouth->token ) >= 10 ) {
5301 bonus_clothing_map[body_part_mouth].clear();
5302 }
5303
5304 std::map<bodypart_id, int> warmth_per_bp = warmth::from_clothing( clothing_map );
5305 std::map<bodypart_id, int> bonus_warmth_per_bp = warmth::bonus_from_clothing( bonus_clothing_map );
5306 for( const auto &pr : warmth::from_effects( *this ) ) {
5307 warmth_per_bp[pr.first] += pr.second;
5308 }
5309
5310 std::map<bodypart_id, int> wind_res_per_bp = warmth::wind_resistance_from_clothing( clothing_map );
5311 std::map<bodypart_id, int> wind_res_per_bp_bonus = warmth::wind_resistance_from_clothing(
5312 bonus_clothing_map );
5313 for( std::pair<const bodypart_id, int> &bp_wind_res : wind_res_per_bp ) {
5314 int exposed = std::max( 0, 100 - bp_wind_res.second );
5315 int exposed_bonus = std::max( 0, 100 - wind_res_per_bp_bonus.at( bp_wind_res.first ) );
5316 int exposed_final = exposed * exposed_bonus / ( 100 * 100 );
5317 bp_wind_res.second = 100 - exposed_final;
5318 }
5320 for( std::pair<const bodypart_id, int> &bp_wind_res : wind_res_per_bp ) {
5321 bp_wind_res.second = 100;
5322 }
5323 }
5324 // We might not use this at all, so leave it empty
5325 // If we do need to use it, we'll initialize it (once) there
5326 std::map<bodypart_id, int> fire_armor_per_bp;
5327
5328 // Current temperature and converging temperature calculations
5329 for( const bodypart_id &bp : get_all_body_parts() ) {
5330 // Skip eyes
5331 if( bp == bodypart_id( "eyes" ) ) {
5332 continue;
5333 }
5334
5335 const bool submerged_bp = submerged ||
5336 ( submerged_low &&
5337 ( bp == body_part_foot_l ||
5338 bp == body_part_foot_r ||
5339 bp == body_part_leg_l ||
5340 bp == body_part_leg_r ) );
5341 // This adjusts the temperature scale to match the bodytemp scale
5342 const int adjusted_temp = submerged_bp ?
5343 water_temperature :
5344 ( Ctemperature - ambient_norm );
5345
5346 // Represents the fact that the body generates heat when it is cold.
5347 double scaled_temperature = logarithmic_range( BODYTEMP_VERY_COLD, BODYTEMP_VERY_HOT,
5348 temp_cur[bp->token] );
5349 // Produces a smooth curve between 30.0 and 60.0.
5350 double homeostasis_adjustment = 30.0 * ( 1.0 + scaled_temperature );
5351 int clothing_warmth_adjustment = static_cast<int>( homeostasis_adjustment * warmth_per_bp[bp] );
5352 int clothing_warmth_adjusted_bonus = static_cast<int>( homeostasis_adjustment *
5353 bonus_warmth_per_bp[bp] );
5354 // WINDCHILL
5355 double bp_windpower = total_windpower * ( 1 - wind_res_per_bp[bp] / 100.0 );
5356 // Calculate windchill
5357 int windchill = submerged_bp
5358 ? 0
5359 : get_local_windchill( player_local_temp,
5360 air_humidity,
5361 bp_windpower );
5362
5363 // Convergent temperature is affected by ambient temperature,
5364 // clothing warmth, and body wetness.
5365 int bp_conv = adjusted_temp
5366 + windchill * 100
5367 + clothing_warmth_adjustment
5368 + mutation_heat_low
5369 + sunlight_warmth;
5370
5371 // Bark : lowers blister count to -5; harder to get blisters
5372 // If the counter is high, your skin starts to burn
5373 int blister_count = ( has_bark ? -5 : 0 );
5374
5375 if( frostbite_timer[bp->token] > 0 ) {
5376 frostbite_timer[bp->token] -= std::min( 5, h_radiation );
5377 }
5378 blister_count += h_radiation - 111 > 0 ?
5379 std::max( static_cast<int>( std::sqrt( h_radiation - 111 ) ), 0 ) : 0;
5380
5381 if( has_heatsink ) {
5382 blister_count -= 20;
5383 }
5384 if( fire_armor_per_bp.empty() && blister_count > 0 ) {
5385 fire_armor_per_bp = get_armor_fire( clothing_map );
5386 }
5387 // BLISTERS : Skin gets blisters from intense heat exposure.
5388 // Fire protection protects from blisters.
5389 // Heatsinks give near-immunity.
5390 if( blister_count - fire_armor_per_bp[bp] > 0 ) {
5391 add_effect( effect_blisters, 1_turns, bp->token );
5392 if( pyromania ) {
5393 add_morale( MORALE_PYROMANIA_NEARFIRE, 10, 10, 1_hours,
5394 30_minutes ); // Proximity that's close enough to harm us gives us a bit of a thrill
5396 }
5397 } else if( pyromania && best_fire >= 1 ) { // Only give us fire bonus if there's actually fire
5398 add_morale( MORALE_PYROMANIA_NEARFIRE, 5, 5, 30_minutes,
5399 15_minutes ); // Gain a much smaller mood boost even if it doesn't hurt us
5401 }
5402
5403 // Climate Control eases the effects of high and low ambient temps
5404 if( has_climate_control ) {
5405 bp_conv = temp_corrected_by_climate_control( bp_conv );
5406 }
5407
5408 int bonus_fire_warmth = best_fire * 500;
5409
5410 const int comfortable_warmth = bonus_fire_warmth + lying_warmth;
5411 const int bonus_warmth = comfortable_warmth + mutation_heat_bonus + clothing_warmth_adjusted_bonus;
5412 if( bonus_warmth > 0 ) {
5413 // Approximate bp_conv needed to reach comfortable temperature in this very turn
5414 // Basically inverted formula for temp_cur below
5415 int desired = 501 * BODYTEMP_NORM - 499 * temp_cur[bp->token];
5416 if( std::abs( BODYTEMP_NORM - desired ) < 1000 ) {
5417 desired = BODYTEMP_NORM; // Ensure that it converges
5418 } else if( desired > BODYTEMP_HOT ) {
5419 desired = BODYTEMP_HOT; // Cap excess at sane temperature
5420 }
5421
5422 if( desired < bp_conv ) {
5423 // Too hot, can't help here
5424 } else if( desired < bp_conv + bonus_warmth ) {
5425 // Use some heat, but not all of it
5426 bp_conv = desired;
5427 } else {
5428 // Use all the heat
5429 bp_conv += bonus_warmth;
5430 }
5431
5432 // Morale bonus for comfiness - only if actually comfy (not too warm/cold)
5433 // Spread the morale bonus in time.
5434 if( comfortable_warmth > 0 &&
5435 // TODO: make this simpler and use time_duration/time_point
5436 to_turn<int>( calendar::turn ) % to_turns<int>( 1_minutes ) == to_turns<int>
5437 ( 1_minutes * bp->token ) / to_turns<int>( 1_minutes * num_bp ) &&
5439 get_effect_int( effect_hot, num_bp ) == 0 &&
5440 temp_cur[bp->token] > BODYTEMP_COLD && temp_cur[bp->token] <= BODYTEMP_NORM ) {
5441 add_morale( MORALE_COMFY, 1, 10, 2_minutes, 1_minutes, true );
5442 }
5443 }
5444
5445 // The current temperature model can't account for water temperature conduction well
5446 // Hack: cut non-water effects by 80% when in water
5447 if( submerged_bp ) {
5448 bp_conv = ( ( bp_conv - adjusted_temp ) / 5 ) + adjusted_temp;
5449 }
5450
5451 // FINAL CALCULATION : Increments current body temperature towards convergent.
5452 int temp_before = temp_cur[bp->token];
5453 int temp_difference = temp_before - bp_conv; // Negative if the player is warming up.
5454 int rounding_error = 0;
5455 // If temp_diff is small, the player cannot warm up due to rounding errors. This fixes that.
5456 if( temp_difference < 0 && temp_difference > -600 ) {
5457 rounding_error = 1;
5458 }
5459 // exp(-0.001) : half life of 60 minutes, exp(-0.002) : half life of 30 minutes,
5460 // exp(-0.003) : half life of 20 minutes, exp(-0.004) : half life of 15 minutes
5461 static const double change_mult_air = std::exp( -0.002 );
5462 static const double change_mult_water = std::exp( -0.008 );
5463 const double change_mult = submerged_bp ? change_mult_water : change_mult_air;
5464 if( temp_cur[bp->token] != bp_conv ) {
5465 temp_cur[bp->token] = static_cast<int>( temp_difference * change_mult )
5466 + bp_conv + rounding_error;
5467 }
5468 int temp_after = temp_cur[bp->token];
5469 // PENALTIES
5470 if( temp_cur[bp->token] < BODYTEMP_FREEZING ) {
5471 add_effect( effect_cold, 1_turns, bp->token, 3 );
5472 } else if( temp_cur[bp->token] < BODYTEMP_VERY_COLD ) {
5473 add_effect( effect_cold, 1_turns, bp->token, 2 );
5474 } else if( temp_cur[bp->token] < BODYTEMP_COLD ) {
5475 add_effect( effect_cold, 1_turns, bp->token, 1 );
5476 } else if( temp_cur[bp->token] > BODYTEMP_SCORCHING ) {
5477 add_effect( effect_hot, 1_turns, bp->token, 3 );
5478 if( bp->main_part.id() == bp ) {
5479 add_effect( effect_hot_speed, 1_turns, bp->token, 3 );
5480 }
5481 } else if( temp_cur[bp->token] > BODYTEMP_VERY_HOT ) {
5482 add_effect( effect_hot, 1_turns, bp->token, 2 );
5483 if( bp->main_part.id() == bp ) {
5484 add_effect( effect_hot_speed, 1_turns, bp->token, 2 );
5485 }
5486 } else if( temp_cur[bp->token] > BODYTEMP_HOT ) {
5487 add_effect( effect_hot, 1_turns, bp->token, 1 );
5488 if( bp->main_part.id() == bp ) {
5489 add_effect( effect_hot_speed, 1_turns, bp->token, 1 );
5490 }
5491 } else {
5492 if( temp_cur[bp->token] >= BODYTEMP_COLD ) {
5493 remove_effect( effect_cold, bp->token );
5494 }
5495 if( temp_cur[bp->token] <= BODYTEMP_HOT ) {
5496 remove_effect( effect_hot, bp->token );
5497 remove_effect( effect_hot_speed, bp->token );
5498 }
5499 }
5500
5501 // FROSTBITE - only occurs to hands, feet, face
5502 /**
5503
5504 Source : http://www.atc.army.mil/weather/windchill.pdf
5505
5506 Temperature and wind chill are main factors, mitigated by clothing warmth. Each 10 warmth protects against 2C of cold.
5507
5508 1200 turns in low risk, + 3 tics
5509 450 turns in moderate risk, + 8 tics
5510 50 turns in high risk, +72 tics
5511
5512 Let's say frostnip @ 1800 tics, frostbite @ 3600 tics
5513
5514 >> Chunked into 8 parts (http://imgur.com/xlTPmJF)
5515 -- 2 hour risk --
5516 Between 30F and 10F
5517 Between 10F and -5F, less than 20mph, -4x + 3y - 20 > 0, x : F, y : mph
5518 -- 45 minute risk --
5519 Between 10F and -5F, less than 20mph, -4x + 3y - 20 < 0, x : F, y : mph
5520 Between 10F and -5F, greater than 20mph
5521 Less than -5F, less than 10 mph
5522 Less than -5F, more than 10 mph, -4x + 3y - 170 > 0, x : F, y : mph
5523 -- 5 minute risk --
5524 Less than -5F, more than 10 mph, -4x + 3y - 170 < 0, x : F, y : mph
5525 Less than -35F, more than 10 mp
5526 **/
5527
5528 if( bp == body_part_mouth || bp == body_part_foot_r ||
5529 bp == body_part_foot_l || bp == body_part_hand_r || bp == body_part_hand_l ) {
5530 // Handle the frostbite timer
5531 // Need temps in F, windPower already in mph
5532 int wetness_percentage = 100 * body_wetness[bp->token] / drench_capacity[bp->token]; // 0 - 100
5533 // Warmth gives a slight buff to temperature resistance
5534 // Wetness gives a heavy nerf to temperature resistance
5535 double adjusted_warmth = warmth_per_bp.at( bp ) - wetness_percentage;
5536 int Ftemperature = static_cast<int>( player_local_temp + 0.2 * adjusted_warmth );
5537 // Windchill reduced by your armor
5538 int FBwindPower = static_cast<int>(
5539 total_windpower * ( 1 - wind_res_per_bp[ bp ] / 100.0 ) );
5540
5541 int intense = get_effect_int( effect_frostbite, bp->token );
5542
5543 // This has been broken down into 8 zones
5544 // Low risk zones (stops at frostnip)
5545 if( temp_cur[bp->token] < BODYTEMP_COLD &&
5546 ( ( Ftemperature < 30 && Ftemperature >= 10 ) ||
5547 ( Ftemperature < 10 && Ftemperature >= -5 &&
5548 FBwindPower < 20 && -4 * Ftemperature + 3 * FBwindPower - 20 >= 0 ) ) ) {
5549 if( frostbite_timer[bp->token] < 2000 ) {
5550 frostbite_timer[bp->token] += 3;
5551 }
5552 if( one_in( 100 ) && !has_effect( effect_frostbite, bp->token ) ) {
5553 add_msg( m_warning, _( "Your %s will be frostnipped in the next few hours." ),
5554 body_part_name( bp->token ) );
5555 }
5556 // Medium risk zones
5557 } else if( temp_cur[bp->token] < BODYTEMP_COLD &&
5558 ( ( Ftemperature < 10 && Ftemperature >= -5 && FBwindPower < 20 &&
5559 -4 * Ftemperature + 3 * FBwindPower - 20 < 0 ) ||
5560 ( Ftemperature < 10 && Ftemperature >= -5 && FBwindPower >= 20 ) ||
5561 ( Ftemperature < -5 && FBwindPower < 10 ) ||
5562 ( Ftemperature < -5 && FBwindPower >= 10 &&
5563 -4 * Ftemperature + 3 * FBwindPower - 170 >= 0 ) ) ) {
5564 frostbite_timer[bp->token] += 8;
5565 if( one_in( 100 ) && intense < 2 ) {
5566 add_msg( m_warning, _( "Your %s will be frostbitten within the hour!" ),
5567 body_part_name( bp->token ) );
5568 }
5569 // High risk zones
5570 } else if( temp_cur[bp->token] < BODYTEMP_COLD &&
5571 ( ( Ftemperature < -5 && FBwindPower >= 10 &&
5572 -4 * Ftemperature + 3 * FBwindPower - 170 < 0 ) ||
5573 ( Ftemperature < -35 && FBwindPower >= 10 ) ) ) {
5574 frostbite_timer[bp->token] += 72;
5575 if( one_in( 100 ) && intense < 2 ) {
5576 add_msg( m_warning, _( "Your %s will be frostbitten any minute now!" ),
5577 body_part_name( bp->token ) );
5578 }
5579 // Risk free, so reduce frostbite timer
5580 } else {
5581 frostbite_timer[bp->token] -= 3;
5582 }
5583
5584 // Handle the bestowing of frostbite
5585 if( frostbite_timer[bp->token] < 0 ) {
5586 frostbite_timer[bp->token] = 0;
5587 } else if( frostbite_timer[bp->token] > 4200 ) {
5588 // This ensures that the player will recover in at most 3 hours.
5589 frostbite_timer[bp->token] = 4200;
5590 }
5591 // Frostbite, no recovery possible
5592 if( frostbite_timer[bp->token] >= 3600 ) {
5593 add_effect( effect_frostbite, 1_turns, bp->token, 2 );
5595 // Else frostnip, add recovery if we were frostbitten
5596 } else if( frostbite_timer[bp->token] >= 1800 ) {
5597 if( intense == 2 ) {
5598 add_effect( effect_frostbite_recovery, 1_turns, bp->token );
5599 }
5600 add_effect( effect_frostbite, 1_turns, bp->token, 1 );
5601 // Else fully recovered
5602 } else if( frostbite_timer[bp->token] == 0 ) {
5603 remove_effect( effect_frostbite, bp->token );
5605 }
5606 }
5607 // Warn the player if condition worsens
5608 // HACK: we want overall temperature change, including equalization, and temp_conv
5609 // at this moment contains temperature values from before the equalization.
5610 temp_before = temp_conv[bp->token];
5611 if( temp_before > BODYTEMP_FREEZING && temp_after <= BODYTEMP_FREEZING ) {
5612 //~ %s is bodypart
5613 add_msg( m_warning, _( "You feel your %s beginning to go numb from the cold!" ),
5614 body_part_name( bp->token ) );
5615 } else if( temp_before > BODYTEMP_VERY_COLD && temp_after <= BODYTEMP_VERY_COLD ) {
5616 //~ %s is bodypart
5617 add_msg( m_warning, _( "You feel your %s getting very cold." ),
5618 body_part_name( bp->token ) );
5619 } else if( temp_before > BODYTEMP_COLD && temp_after <= BODYTEMP_COLD ) {
5620 //~ %s is bodypart
5621 add_msg( m_warning, _( "You feel your %s getting chilly." ),
5622 body_part_name( bp->token ) );
5623 } else if( temp_before < BODYTEMP_SCORCHING && temp_after >= BODYTEMP_SCORCHING ) {
5624 //~ %s is bodypart
5625 add_msg( m_bad, _( "You feel your %s getting red hot from the heat!" ),
5626 body_part_name( bp->token ) );
5627 } else if( temp_before < BODYTEMP_VERY_HOT && temp_after >= BODYTEMP_VERY_HOT ) {
5628 //~ %s is bodypart
5629 add_msg( m_warning, _( "You feel your %s getting very hot." ),
5630 body_part_name( bp->token ) );
5631 } else if( temp_before < BODYTEMP_HOT && temp_after >= BODYTEMP_HOT ) {
5632 //~ %s is bodypart
5633 add_msg( m_warning, _( "You feel your %s getting warm." ),
5634 body_part_name( bp->token ) );
5635 }
5636
5637 // Note: Numbers are based off of BODYTEMP at the top of weather.h
5638 // If torso is BODYTEMP_COLD which is 34C, the early stages of hypothermia begin
5639 // constant shivering will prevent the player from falling asleep.
5640 // Otherwise, if any other body part is BODYTEMP_VERY_COLD, or 31C
5641 // AND you have frostbite, then that also prevents you from sleeping
5642 if( in_sleep_state() ) {
5643 int curr_temperature = temp_cur[bp->token];
5644 if( bp == body_part_torso && curr_temperature <= BODYTEMP_COLD ) {
5645 add_msg( m_warning, _( "Your shivering prevents you from sleeping." ) );
5646 wake_up();
5647 } else if( bp != body_part_torso && curr_temperature <= BODYTEMP_VERY_COLD &&
5649 add_msg( m_warning, _( "You are too cold. Your frostbite prevents you from sleeping." ) );
5650 wake_up();
5651 }
5652 }
5653
5654 // Warn the player that wind is going to be a problem.
5655 // But only if it can be a problem, no need to spam player with "wind chills your scorching body"
5656 if( bp_conv <= BODYTEMP_COLD && windchill < -10 && one_in( 200 ) ) {
5657 add_msg( m_bad, _( "The wind is making your %s feel quite cold." ),
5658 body_part_name( bp->token ) );
5659 } else if( bp_conv <= BODYTEMP_COLD && windchill < -20 && one_in( 100 ) ) {
5660 add_msg( m_bad,
5661 _( "The wind is very strong, you should find some more wind-resistant clothing for your %s." ),
5662 body_part_name( bp->token ) );
5663 } else if( bp_conv <= BODYTEMP_COLD && windchill < -30 && one_in( 50 ) ) {
5664 add_msg( m_bad, _( "Your clothing is not providing enough protection from the wind for your %s!" ),
5665 body_part_name( bp->token ) );
5666 }
5667
5668 // Set temp_conv just once per bp for readability
5669 // TODO: Remove temp_conv, it's only really for display, so should not be in Character
5670 temp_conv[bp->token] = bp_conv;
5671 }
5672}
const bodypart_str_id body_part_foot_r("foot_r")
const bodypart_str_id body_part_hand_r("hand_r")
const bodypart_str_id body_part_leg_l("leg_l")
const bodypart_str_id body_part_arm_l("arm_l")
const bodypart_str_id body_part_torso("torso")
const bodypart_str_id body_part_arm_r("arm_r")
const bodypart_str_id body_part_leg_r("leg_r")
const bodypart_str_id body_part_mouth("mouth")
const bodypart_str_id body_part_head("head")
const bodypart_str_id body_part_hand_l("hand_l")
const bodypart_str_id body_part_foot_l("foot_l")
static const efftype_id effect_cold("cold")
static const trait_id trait_DEBUG_NOTEMP("DEBUG_NOTEMP")
static const trait_id trait_BARK("BARK")
static const flag_str_id flag_POCKETS("POCKETS")
static const efftype_id effect_hot("hot")
static const flag_str_id flag_HOOD("HOOD")
static const trait_id trait_PYROMANIA("PYROMANIA")
static const efftype_id effect_blisters("blisters")
static const efftype_id effect_frostbite_recovery("frostbite_recovery")
static const efftype_id effect_hot_speed("hot_speed")
static const flag_str_id flag_COLLAR("COLLAR")
static const efftype_id effect_frostbite("frostbite")
int temp_corrected_by_climate_control(int temperature) const
Value of the body temperature corrected by climate control.
Definition: character.cpp:9515
std::map< bodypart_id, int > get_armor_fire(const std::map< bodypart_id, std::vector< const item * > > &clothing_map) const
Returns overall fire resistance.
Definition: character.cpp:8207
bool can_use_floor_warmth() const
Can the player lie down and cover self with blankets etc.
Definition: character.cpp:9396
int bodytemp_modifier_traits(bool overheated) const
Correction factor of the body temperature due to traits and mutations.
Definition: character.cpp:9497
bool in_climate_control()
Returns true if the player is in a climate controlled area or armor.
Definition: character.cpp:3816
void temp_equalizer(const bodypart_id &bp1, const bodypart_id &bp2)
Equalizes heat between body parts.
Definition: character.cpp:5674
int floor_warmth(const tripoint &pos) const
Final warmth from the floor.
Definition: character.cpp:9482
int get_heat_radiation(const tripoint &location, bool direct)
Definition: game.cpp:1800
const morale_type MORALE_COMFY("morale_comfy")
constexpr double fahrenheit_to_celsius(double fahrenheit)
std::map< bodypart_id, int > bonus_from_clothing(const std::map< bodypart_id, std::vector< const item * > > &clothing_map)
Definition: character.cpp:9379
std::map< bodypart_id, int > wind_resistance_from_clothing(const std::map< bodypart_id, std::vector< const item * > > &clothing_map)
Returns wind resistance provided by armor, etc.
Definition: character.cpp:3872
std::map< bodypart_id, int > from_effects(const Character &c)
Definition: character.cpp:9385
std::map< bodypart_id, int > from_clothing(const std::map< bodypart_id, std::vector< const item * > > &clothing_map)
Definition: character.cpp:9373
bool is_in_sunlight(const map &m, const tripoint &p, const weather_type_id &weather)
Definition: weather.cpp:1162
bool is_sheltered(const map &m, const tripoint &p)
Definition: weather.cpp:1153
bool has_flag(const std::string &flag) const
Definition: mapdata.h:419

References _, Creature::add_effect(), add_morale(), add_msg(), bio_heatsink, body_part_arm_l, body_part_arm_r, body_part_foot_l, body_part_foot_r, body_part_hand_l, body_part_hand_r, body_part_head, body_part_leg_l, body_part_leg_r, body_part_mouth, body_part_name(), body_part_torso, body_wetness, BODYTEMP_COLD, BODYTEMP_FREEZING, BODYTEMP_HOT, bodytemp_modifier_traits(), BODYTEMP_NORM, BODYTEMP_SCORCHING, BODYTEMP_VERY_COLD, BODYTEMP_VERY_HOT, warmth::bonus_from_clothing(), can_use_floor_warmth(), convert_bp(), drench_capacity, effect_blisters, effect_cold, effect_frostbite, effect_frostbite_recovery, effect_hot, effect_hot_speed, encumb(), units::fahrenheit_to_celsius(), flag_COLLAR, flag_HOOD, flag_POCKETS, floor_warmth(), warmth::from_clothing(), warmth::from_effects(), frostbite_timer, Creature::get_all_body_parts(), get_armor_fire(), Creature::get_effect_int(), get_heat_radiation(), get_local_humidity(), get_local_windchill(), get_local_windpower(), weather_manager::get_precise(), get_weather(), global_omt_location(), has_active_mutation(), has_bionic(), Creature::has_effect(), map_data_common_t::has_flag(), has_trait(), high, w_point::humidity, in_climate_control(), in_sleep_state(), in_vehicle, weather::is_in_sunlight(), weather::is_sheltered(), is_wearing(), itype_rm13_armor_on, logarithmic_range(), m_bad, m_warning, MORALE_COMFY, MORALE_PYROMANIA_NEARFIRE, MORALE_PYROMANIA_NOFIRE, num_bp, one_in(), overmap_buffer, optional_vpart_position::part_with_feature(), pos(), rem_morale(), Creature::remove_effect(), temp_conv, temp_corrected_by_climate_control(), temp_cur, temp_equalizer(), map::ter(), overmapbuffer::ter(), body_part_set::test(), TFLAG_DEEP_WATER, TFLAG_SWIMMABLE, body_part_type::token, trait_BARK, trait_DEBUG_NOTEMP, trait_M_SKIN2, trait_M_SKIN3, trait_PYROMANIA, trait_SHELL2, calendar::turn, map::veh_at(), item::volume(), wake_up(), weapon, warmth::wind_resistance_from_clothing(), and worn.

Referenced by game::do_turn(), and iuse_transform::use().

◆ update_fuel_storage()

void Character::update_fuel_storage ( const itype_id fuel)

Updates which bionic contain fuel and which is empty.

Definition at line 2040 of file character.cpp.

2041{
2042 const item it( fuel );
2043 if( get_value( fuel.str() ).empty() ) {
2044 for( const bionic_id &bid : get_bionic_fueled_with( it ) ) {
2045 remove_value( bid.c_str() );
2046 }
2047 return;
2048 }
2049
2050 std::vector<bionic_id> bids = get_bionic_fueled_with( it );
2051 if( bids.empty() ) {
2052 return;
2053 }
2054 int amount_fuel_loaded = std::stoi( get_value( fuel.str() ) );
2055 std::vector<bionic_id> loaded_bio;
2056
2057 // Sort bionic in order of decreasing capacity
2058 // To fill the bigger ones firts.
2059 bool swap = true;
2060 while( swap ) {
2061 swap = false;
2062 for( size_t i = 0; i < bids.size() - 1; i++ ) {
2063 if( bids[i + 1]->fuel_capacity > bids[i]->fuel_capacity ) {
2064 std::swap( bids[i + 1], bids[i] );
2065 swap = true;
2066 }
2067 }
2068 }
2069
2070 for( const bionic_id &bid : bids ) {
2071 remove_value( bid.c_str() );
2072 if( bid->fuel_capacity <= amount_fuel_loaded ) {
2073 amount_fuel_loaded -= bid->fuel_capacity;
2074 loaded_bio.emplace_back( bid );
2075 } else if( amount_fuel_loaded != 0 ) {
2076 loaded_bio.emplace_back( bid );
2077 break;
2078 }
2079 }
2080
2081 for( const bionic_id &bd : loaded_bio ) {
2082 set_value( bd.str(), fuel.str() );
2083 }
2084
2085}
void swap(colony< element_type, element_allocator_type, element_skipfield_type > &a, colony< element_type, element_allocator_type, element_skipfield_type > &b) COLONY_NOEXCEPT_SWAP(element_allocator_type)
Swaps colony A's contents with that of colony B.
Definition: colony.h:3496

References get_bionic_fueled_with(), Creature::get_value(), Creature::remove_value(), Creature::set_value(), string_id< T >::str(), and cata::swap().

Referenced by burn_fuel(), and fuel_bionic_with().

◆ update_health()

void Character::update_health ( int  external_modifiers = 0)
virtual

Handles health fluctuations over time.

Definition at line 4609 of file character.cpp.

4610{
4611 if( has_artifact_with( AEP_SICK ) ) {
4612 // Carrying a sickness artifact makes your health 50 points worse on average
4613 external_modifiers -= 50;
4614 }
4615 // Limit healthy_mod to [-200, 200].
4616 // This also sets approximate bounds for the character's health.
4617 if( get_healthy_mod() > get_max_healthy() ) {
4619 } else if( get_healthy_mod() < -200 ) {
4620 set_healthy_mod( -200 );
4621 }
4622
4623 // Active leukocyte breeder will keep your health near 100
4624 int effective_healthy_mod = get_healthy_mod();
4626 // Side effect: dependency
4627 mod_healthy_mod( -50, -200 );
4628 effective_healthy_mod = 100;
4629 }
4630
4631 // Health tends toward healthy_mod.
4632 // For small differences, it changes 4 points per day
4633 // For large ones, up to ~40% of the difference per day
4634 int health_change = effective_healthy_mod - get_healthy() + external_modifiers;
4635 mod_healthy( sgn( health_change ) * std::max( 1, std::abs( health_change ) / 10 ) );
4636
4637 // And healthy_mod decays over time.
4638 // Slowly near 0, but it's hard to overpower it near +/-100
4639 set_healthy_mod( std::round( get_healthy_mod() * 0.95f ) );
4640
4641 add_msg( m_debug, "Health: %d, Health mod: %d", get_healthy(), get_healthy_mod() );
4642}
static const bionic_id bio_leukocyte("bio_leukocyte")
int get_max_healthy() const
Definition: character.cpp:4531
@ AEP_SICK
Definition: enums.h:141

References add_msg(), AEP_SICK, bio_leukocyte, get_healthy(), get_healthy_mod(), get_max_healthy(), has_active_bionic(), has_artifact_with(), m_debug, mod_healthy(), mod_healthy_mod(), set_healthy_mod(), and sgn().

Referenced by update_body().

◆ update_morale()

void Character::update_morale ( )

Ticks down morale counters and removes them.

Definition at line 8956 of file character.cpp.

8957{
8958 morale->decay( 1_minutes );
8960}

References apply_persistent_morale(), and morale.

Referenced by game::do_turn().

◆ update_needs()

void Character::update_needs ( int  rate_multiplier)

Increases hunger, thirst, fatigue and stimulants wearing off.

rate_multiplier is for retroactive updates.

Definition at line 4764 of file character.cpp.

4765{
4766 const int current_stim = get_stim();
4767 // Hunger, thirst, & fatigue up every 5 minutes
4769 // No food/thirst/fatigue clock at all
4770 const bool debug_ls = has_trait( trait_DEBUG_LS );
4771 // No food/thirst, capped fatigue clock (only up to tired)
4772 const bool npc_no_food = is_npc() && get_option<bool>( "NO_NPC_FOOD" );
4773 const bool asleep = !sleep.is_null();
4774 const bool lying = asleep || has_effect( effect_lying_down ) ||
4776
4777 needs_rates rates = calc_needs_rates();
4778
4779 const bool wasnt_fatigued = get_fatigue() <= fatigue_levels::dead_tired;
4780 // Don't increase fatigue if sleeping or trying to sleep or if we're at the cap.
4781 if( get_fatigue() < 1050 && !asleep && !debug_ls ) {
4782 if( rates.fatigue > 0.0f ) {
4783 int fatigue_roll = roll_remainder( rates.fatigue * rate_multiplier );
4784 mod_fatigue( fatigue_roll );
4785
4786 // Synaptic regen bionic stops SD while awake and boosts it while sleeping
4788 // fatigue_roll should be around 1 - so the counter increases by 1 every minute on average,
4789 // but characters who need less sleep will also get less sleep deprived, and vice-versa.
4790
4791 // Note: Since needs are updated in 5-minute increments, we have to multiply the roll again by
4792 // 5. If rate_multiplier is > 1, fatigue_roll will be higher and this will work out.
4793 mod_sleep_deprivation( fatigue_roll * 5 );
4794 }
4795
4796 if( npc_no_food && get_fatigue() > fatigue_levels::tired ) {
4797 set_fatigue( static_cast<int>( fatigue_levels::tired ) );
4798 }
4799 if( npc_no_food ) {
4801 }
4802 }
4803 } else if( asleep && rates.recovery > 0.0f ) {
4804 int recovered = roll_remainder( rates.recovery * rate_multiplier );
4805 // Hibernation prevents waking up until you're hungry or thirsty
4806 if( get_fatigue() - recovered < -20 && !is_hibernating() ) {
4807 // Should be wake up, but that could prevent some retroactive regeneration
4808 sleep.set_duration( 1_turns );
4809 mod_fatigue( -25 );
4810 } else {
4812 recovered *= .5;
4813 }
4814 mod_fatigue( -recovered );
4815
4816 float rest_modifier = 1.0f;
4817 // Bionic doubles the base regen
4819 rest_modifier += 1.0f;
4820 }
4822 rest_modifier += 0.2f;
4823 }
4824
4825 const character_funcs::comfort_level comfort =
4827
4828 // Best possible bed increases recovery by 30% of base
4830 rest_modifier += 0.3f;
4831 } else if( comfort >= character_funcs::comfort_level::comfortable ) {
4832 rest_modifier += 0.2f;
4834 rest_modifier += 0.1f;
4835 }
4836
4837 // 6 hours of sleep per day will let you avoid deprivation
4838 // 4 hours if on great bed plus melatonin
4839 // Math: 5 (fatigue to minutes), 3 (1:3 sleep to waking),
4840 // 2 (legacy sleep non-linearity thing)
4841 mod_sleep_deprivation( -rest_modifier * ( recovered * 3.0f * 5.0f / 2.0f ) );
4842
4843 }
4844 }
4845 if( is_player() && wasnt_fatigued && get_fatigue() > fatigue_levels::dead_tired && !lying ) {
4846 if( !activity ) {
4847 add_msg_if_player( m_warning, _( "You're feeling tired. %s to lie down for sleep." ),
4848 press_x( ACTION_SLEEP ) );
4849 } else {
4850 g->cancel_activity_query( _( "You're feeling tired." ) );
4851 }
4852 }
4853
4854 if( current_stim < 0 ) {
4855 set_stim( std::min( current_stim + rate_multiplier, 0 ) );
4856 } else if( current_stim > 0 ) {
4857 set_stim( std::max( current_stim - rate_multiplier, 0 ) );
4858 }
4859
4860 if( get_painkiller() > 0 ) {
4861 mod_painkiller( -std::min( get_painkiller(), rate_multiplier ) );
4862 }
4863
4864 // Huge folks take penalties for cramming themselves in vehicles
4865 if( in_vehicle && ( get_size() == MS_HUGE )
4867 vehicle *veh = veh_pointer_or_null( get_map().veh_at( pos() ) );
4868 // it's painful to work the controls, but passengers in open topped vehicles are fine
4869 if( veh && ( veh->enclosed_at( pos() ) || veh->player_in_control( *this->as_player() ) ) ) {
4871 _( "You're cramping up from stuffing yourself in this vehicle." ) );
4872 if( is_npc() ) {
4873 npc &as_npc = dynamic_cast<npc &>( *this );
4874 as_npc.complain_about( "cramped_vehicle", 1_hours, "<cramped_vehicle>", false );
4875 }
4876
4877 mod_pain( rng( 4, 6 ) );
4878 focus_pool -= 1;
4879 }
4880 }
4881}
std::string press_x(action_id act)
Definition: action.cpp:457
@ ACTION_SLEEP
Open sleep menu.
Definition: action.h:209
static const efftype_id effect_melatonin_supplements("melatonin")
static const trait_id trait_DEBUG_LS("DEBUG_LS")
static const bionic_id bio_synaptic_regen("bio_synaptic_regen")
static const efftype_id effect_lying_down("lying_down")
needs_rates calc_needs_rates() const
Definition: character.cpp:4882
virtual void mod_sleep_deprivation(int nsleep_deprivation)
Definition: character.cpp:4423
virtual npc * as_npc()
Definition: creature.h:110
bool complain_about(const std::string &issue, const time_duration &dur, const std::string &speech, bool force=false, sounds::sound_t priority=sounds::sound_t::speech)
Definition: npcmove.cpp:4444
bool enclosed_at(const tripoint &pos)
Definition: vehicle.cpp:6287
comfort_response_t base_comfort_value(const Character &who, const tripoint &p)
Rate point's ability to serve as a bed.

References _, ACT_TRY_SLEEP, ACTION_SLEEP, activity, Creature::add_msg_if_player(), Creature::as_npc(), character_funcs::base_comfort_value(), bio_synaptic_regen, calc_needs_rates(), character_funcs::comfortable, npc::complain_about(), dead_tired, effect_lying_down, effect_melatonin_supplements, effect_narcosis, effect_recently_coughed, effect_sleep, vehicle::enclosed_at(), needs_rates::fatigue, focus_pool, g, Creature::get_effect(), get_fatigue(), get_map(), get_painkiller(), get_size(), get_stim(), has_active_bionic(), Creature::has_effect(), has_trait(), player_activity::id(), in_vehicle, is_hibernating(), Creature::is_npc(), Creature::is_player(), character_funcs::comfort_response_t::level, m_bad, m_warning, mod_fatigue(), mod_pain(), mod_painkiller(), mod_sleep_deprivation(), MS_HUGE, vehicle::player_in_control(), pos(), press_x(), needs_rates::recovery, rng(), roll_remainder(), set_fatigue(), set_sleep_deprivation(), set_stim(), sleep, character_funcs::slightly_comfortable, tired, trait_DEBUG_LS, trait_NOPAIN, veh_pointer_or_null(), and character_funcs::very_comfortable.

Referenced by update_body().

◆ update_stamina()

void Character::update_stamina ( int  turns)

Regenerates stamina.

Definition at line 7128 of file character.cpp.

7129{
7130 static const std::string player_base_stamina_regen_rate( "PLAYER_BASE_STAMINA_REGEN_RATE" );
7131 static const std::string stamina_regen_modifier( "stamina_regen_modifier" );
7132 const float base_regen_rate = get_option<float>( player_base_stamina_regen_rate );
7133 const int current_stim = get_stim();
7134 float stamina_recovery = 0.0f;
7135 // Recover some stamina every turn.
7136 // max stamina modifers from mutation also affect stamina multi
7137 float stamina_multiplier = 1.0f + mutation_value( stamina_regen_modifier ) +
7138 ( mutation_value( "max_stamina_modifier" ) - 1.0f ) +
7140 // But mouth encumbrance interferes, even with mutated stamina.
7141 stamina_recovery += stamina_multiplier * std::max( 1.0f,
7142 base_regen_rate - ( encumb( bp_mouth ) / 5.0f ) );
7143 // TODO: recovering stamina causes hunger/thirst/fatigue.
7144 // TODO: Tiredness slowing recovery
7145
7146 // stim recovers stamina (or impairs recovery)
7147 if( current_stim > 0 ) {
7148 // TODO: Make stamina recovery with stims cost health
7149 stamina_recovery += std::min( 5.0f, current_stim / 15.0f );
7150 } else if( current_stim < 0 ) {
7151 // Affect it less near 0 and more near full
7152 // Negative stim kill at -200
7153 // At -100 stim it inflicts -20 malus to regen at 100% stamina,
7154 // effectivly countering stamina gain of default 20,
7155 // at 50% stamina its -10 (50%), cuts by 25% at 25% stamina
7156 // FIXME: this formula is only suitable for advancing by 1 turn
7157 stamina_recovery += current_stim / 5.0f * get_stamina() / get_stamina_max();
7158 }
7159 stamina_recovery = std::max( 0.0f, stamina_recovery );
7160
7161 const int max_stam = get_stamina_max();
7162 if( get_power_level() >= 3_kJ && has_active_bionic( bio_gills ) ) {
7163 int bonus = std::min<int>( units::to_kilojoule( get_power_level() ) / 3,
7164 max_stam - get_stamina() - stamina_recovery * turns );
7165 // so the effective recovery is up to 5x default
7166 bonus = std::min( bonus, 4 * static_cast<int>( base_regen_rate ) );
7167 if( bonus > 0 ) {
7168 stamina_recovery += bonus;
7169 bonus /= 10;
7170 bonus = std::max( bonus, 1 );
7172 }
7173 }
7174
7175 mod_stamina( roll_remainder( stamina_recovery * turns ) );
7176 add_msg( m_debug, "Stamina recovery: %d", roll_remainder( stamina_recovery * turns ) );
7177 // Cap at max
7178 set_stamina( std::min( std::max( get_stamina(), 0 ), max_stam ) );
7179}
static const bionic_id bio_gills("bio_gills")

References add_msg(), bio_gills, bonus_from_enchantments(), bp_mouth, encumb(), units::from_kilojoule(), get_power_level(), get_stamina(), get_stamina_max(), get_stim(), has_active_bionic(), m_debug, mod_power_level(), mod_stamina(), mutation_value(), roll_remainder(), set_stamina(), enchant_vals::STAMINA_REGEN, and units::to_kilojoule().

Referenced by update_body().

◆ update_stomach()

void Character::update_stomach ( const time_point from,
const time_point to 
)

Updates the stomach to give accurate hunger messages.

Definition at line 4721 of file character.cpp.

4722{
4723 const needs_rates rates = calc_needs_rates();
4724 // No food/thirst/fatigue clock at all
4725 const bool debug_ls = has_trait( trait_DEBUG_LS );
4726 // No food/thirst, capped fatigue clock (only up to tired)
4727 const bool npc_no_food = is_npc() && get_option<bool>( "NO_NPC_FOOD" );
4728 const bool foodless = debug_ls || npc_no_food;
4729 const bool mouse = has_trait( trait_NO_THIRST );
4730 const bool mycus = has_trait( trait_M_DEPENDENT );
4731 const float kcal_per_time = bmr() / ( 12.0f * 24.0f );
4732 const int five_mins = ticks_between( from, to, 5_minutes );
4733
4734 if( five_mins > 0 ) {
4735 // Digest nutrients in stomach
4736 food_summary digested_to_body = stomach.digest( rates, five_mins );
4737 // Apply nutrients, unless this is an NPC and NO_NPC_FOOD is enabled.
4738 if( !npc_no_food ) {
4739 mod_stored_kcal( digested_to_body.nutr.kcal );
4740 vitamins_mod( digested_to_body.nutr.vitamins, false );
4741 }
4742 if( !foodless && rates.hunger > 0.0f ) {
4743 // instead of hunger keeping track of how you're living, burn calories instead
4744 mod_stored_kcal( -roll_remainder( five_mins * kcal_per_time ) );
4745 }
4746 }
4747
4748 if( !foodless && rates.thirst > 0.0f ) {
4749 mod_thirst( roll_remainder( rates.thirst * five_mins ) );
4750 }
4751
4752 if( npc_no_food ) {
4753 set_thirst( static_cast<int>( thirst_levels::hydrated ) );
4755 }
4756
4757 // Mycus and Metabolic Rehydration makes thirst unnecessary
4758 // since water is not limited by intake but by absorption, we can just set thirst to zero
4759 if( mycus || mouse ) {
4760 set_thirst( 0 );
4761 }
4762}
static const trait_id trait_NO_THIRST("NO_THIRST")
static const trait_id trait_M_DEPENDENT("M_DEPENDENT")
void vitamins_mod(const std::map< vitamin_id, int > &, bool capped=true)
food_summary digest(const needs_rates &metabolic_rates, int five_mins)
Processes food and outputs nutrients that are finished processing Metabolic rates are required becaus...
Definition: stomach.cpp:132
int mycus(player *, item *, bool, const tripoint &)
Definition: iuse.cpp:1435
nutrients nutr
Definition: stomach.h:53
std::map< vitamin_id, int > vitamins
vitamins potentially provided by this comestible (if any)
Definition: stomach.h:21

References bmr(), calc_needs_rates(), stomach_contents::digest(), has_trait(), needs_rates::hunger, hydrated, Creature::is_npc(), nutrients::kcal, max_stored_kcal(), mod_stored_kcal(), mod_thirst(), iuse::mycus(), food_summary::nutr, roll_remainder(), set_stored_kcal(), set_thirst(), stomach, needs_rates::thirst, ticks_between(), trait_DEBUG_LS, trait_M_DEPENDENT, trait_NO_THIRST, nutrients::vitamins, and vitamins_mod().

Referenced by update_body().

◆ update_type_of_scent() [1/2]

void Character::update_type_of_scent ( bool  init = false)

Definition at line 8682 of file character.cpp.

8683{
8684 scenttype_id new_scent = scenttype_id( "sc_human" );
8685 for( const trait_id &mut : get_mutations() ) {
8686 if( mut.obj().scent_typeid ) {
8687 new_scent = mut.obj().scent_typeid.value();
8688 }
8689 }
8690
8691 if( !init && new_scent != get_type_of_scent() ) {
8692 g->scent.reset();
8693 }
8694 set_type_of_scent( new_scent );
8695}
scenttype_id get_type_of_scent() const
Definition: character.cpp:8715
Definition: init.h:178

References g, get_mutations(), get_type_of_scent(), mutation_branch::scent_typeid, and set_type_of_scent().

Referenced by on_mutation_gain(), on_mutation_loss(), and update_type_of_scent().

◆ update_type_of_scent() [2/2]

void Character::update_type_of_scent ( const trait_id mut,
bool  gain = true 
)

Definition at line 8697 of file character.cpp.

8698{
8699 const cata::optional<scenttype_id> &mut_scent = mut->scent_typeid;
8700 if( mut_scent ) {
8701 if( gain && mut_scent.value() != get_type_of_scent() ) {
8702 set_type_of_scent( mut_scent.value() );
8703 g->scent.reset();
8704 } else {
8706 }
8707 }
8708}
cata::optional< scenttype_id > scent_typeid
What do you smell like.
Definition: mutation.h:159

References g, get_type_of_scent(), mutation_branch::scent_typeid, set_type_of_scent(), update_type_of_scent(), and cata::optional< T >::value().

◆ update_vitamins()

void Character::update_vitamins ( const vitamin_id vit)

Set vitamin deficiency/excess disease states dependent upon current vitamin levels.

Definition at line 8756 of file character.cpp.

8757{
8758 if( is_npc() ) {
8759 return; // NPCs cannot develop vitamin diseases
8760 }
8761
8762 efftype_id def = vit.obj().deficiency();
8763 efftype_id exc = vit.obj().excess();
8764
8765 int lvl = vit.obj().severity( vitamin_get( vit ) );
8766 if( lvl <= 0 ) {
8767 remove_effect( def );
8768 }
8769 if( lvl >= 0 ) {
8770 remove_effect( exc );
8771 }
8772 if( lvl > 0 ) {
8773 if( has_effect( def, num_bp ) ) {
8774 get_effect( def, num_bp ).set_intensity( lvl, true );
8775 } else {
8776 add_effect( def, 1_turns, num_bp, lvl );
8777 }
8778 }
8779 if( lvl < 0 ) {
8780 if( has_effect( exc, num_bp ) ) {
8781 get_effect( exc, num_bp ).set_intensity( -lvl, true );
8782 } else {
8783 add_effect( exc, 1_turns, num_bp, -lvl );
8784 }
8785 }
8786}
int vitamin_get(const vitamin_id &vit) const
Check current level of a vitamin.
int set_intensity(int val, bool alert=false)
Sets intensity of effect capped by range [1..max_intensity].
Definition: effect.cpp:858
const efftype_id & deficiency() const
Disease effect with increasing intensity proportional to vitamin deficiency.
Definition: vitamin.h:57
const efftype_id & excess() const
Disease effect with increasing intensity proportional to vitamin excess.
Definition: vitamin.h:62
int severity(int qty) const
Get intensity of deficiency or zero if not deficient for specified qty.
Definition: vitamin.cpp:39

References Creature::add_effect(), vitamin::deficiency(), vitamin::excess(), Creature::get_effect(), Creature::has_effect(), Creature::is_npc(), num_bp, string_id< T >::obj(), Creature::remove_effect(), effect::set_intensity(), vitamin::severity(), and vitamin_get().

Referenced by vitamin_mod().

◆ use_amount()

std::list< item > Character::use_amount ( itype_id  it,
int  quantity,
const std::function< bool(const item &)> &  filter = return_true<item> 
)

Definition at line 9582 of file character.cpp.

9584{
9585 std::list<item> ret;
9586 if( weapon.use_amount( it, quantity, ret ) ) {
9587 remove_weapon();
9588 }
9589 for( auto a = worn.begin(); a != worn.end() && quantity > 0; ) {
9590 if( a->use_amount( it, quantity, ret, filter ) ) {
9591 a->on_takeoff( *this );
9592 a = worn.erase( a );
9593 } else {
9594 ++a;
9595 }
9596 }
9597 if( quantity <= 0 ) {
9598 return ret;
9599 }
9600 std::list<item> tmp = inv.use_amount( it, quantity, filter );
9601 ret.splice( ret.end(), tmp );
9602 return ret;
9603}
std::list< item > use_amount(itype_id it, int quantity, const std::function< bool(const item &)> &filter=return_true< item >)
Definition: inventory.cpp:855
bool use_amount(const itype_id &it, int &quantity, std::list< item > &used, const std::function< bool(const item &)> &filter=return_true< item >)
Consume a specific amount of items of a specific type.
Definition: item.cpp:8496
constexpr double a
Definition: magic.cpp:1030

References a, inv, remove_weapon(), cata::hash64_detail::ret, item::use_amount(), inventory::use_amount(), weapon, and worn.

Referenced by computer_session::action_srcf_elevator(), iexamine::cardreader(), iexamine::cardreader_robofac(), player::consume_items(), game::find_or_make_stairs(), hack_attempt(), monexamine::mech_hack(), iexamine::pedestal_temple(), activity_handlers::plant_seed_finish(), vehicle::reload_seeds(), talk_effect_fun_t::set_consume_item(), talk_effect_fun_t::set_u_sell_item(), sinkhole_safety_roll(), and npc_trading::transfer_items().

◆ use_charges()

std::list< item > Character::use_charges ( const itype_id what,
int  qty,
const std::function< bool(const item &)> &  filter = return_true<item> 
)

Definition at line 9614 of file character.cpp.

9616{
9617 std::list<item> res;
9618
9619 if( qty <= 0 ) {
9620 return res;
9621
9622 } else if( what == itype_toolset ) {
9624 return res;
9625
9626 } else if( what == itype_fire ) {
9627 use_fire( qty );
9628 return res;
9629
9630 } else if( what == itype_bio_armor ) {
9631 float mod_qty = 0;
9632 float efficiency = 1;
9633 for( const bionic &bio : *my_bionics ) {
9634 if( bio.powered && bio.info().has_flag( flag_BIONIC_ARMOR_INTERFACE ) ) {
9635 efficiency = std::max( efficiency, bio.info().fuel_efficiency );
9636 }
9637 }
9638 if( efficiency == 1 ) {
9639 debugmsg( "Player lacks a bionic armor interface with fuel efficiency field." );
9640 }
9641 mod_qty = qty / efficiency;
9643 return res;
9644
9645 } else if( what == itype_UPS ) {
9646 if( is_mounted() && mounted_creature.get()->has_flag( MF_RIDEABLE_MECH ) &&
9647 mounted_creature.get()->battery_item ) {
9648 auto mons = mounted_creature.get();
9649 int power_drain = std::min( mons->battery_item->ammo_remaining(), qty );
9650 mons->use_mech_power( -power_drain );
9651 qty -= std::min( qty, power_drain );
9652 return res;
9653 }
9654 if( has_power() && has_active_bionic( bio_ups ) ) {
9655 int bio = std::min( units::to_kilojoule( get_power_level() ), qty );
9657 qty -= std::min( qty, bio );
9658 }
9659
9660 int adv = charges_of( itype_adv_UPS_off, static_cast<int>( std::ceil( qty * 0.6 ) ) );
9661 if( adv > 0 ) {
9662 std::list<item> found = use_charges( itype_adv_UPS_off, adv );
9663 res.splice( res.end(), found );
9664 qty -= std::min( qty, static_cast<int>( adv / 0.6 ) );
9665 }
9666
9667 int ups = charges_of( itype_UPS_off, qty );
9668 if( ups > 0 ) {
9669 std::list<item> found = use_charges( itype_UPS_off, ups );
9670 res.splice( res.end(), found );
9671 qty -= std::min( qty, ups );
9672 }
9673 return res;
9674
9675 }
9676
9677 std::vector<item *> del;
9678
9679 bool has_tool_with_UPS = false;
9680 visit_items( [this, &what, &qty, &res, &del, &has_tool_with_UPS, &filter]( item * e ) {
9681 if( e->use_charges( what, qty, res, pos(), filter ) ) {
9682 del.push_back( e );
9683 }
9684 if( filter( *e ) && e->typeId() == what && e->has_flag( flag_USE_UPS ) ) {
9685 has_tool_with_UPS = true;
9686 }
9687 return qty > 0 ? VisitResponse::SKIP : VisitResponse::ABORT;
9688 } );
9689
9690 for( auto e : del ) {
9691 remove_item( *e );
9692 }
9693
9694 if( has_tool_with_UPS ) {
9695 use_charges( itype_UPS, qty );
9696 }
9697
9698 return res;
9699}
static const itype_id itype_toolset("toolset")
static const itype_id itype_adv_UPS_off("adv_UPS_off")
static const bionic_id bio_ups("bio_ups")
static const itype_id itype_UPS_off("UPS_off")
void use_fire(int quantity)
Definition: character.cpp:9765
bool use_charges(const itype_id &what, int &qty, std::list< item > &used, const tripoint &pos, const std::function< bool(const item &)> &filter=return_true< item >)
Consumes specified charges (or fewer) from this and any contained items.
Definition: item.cpp:8616

References ABORT, bio_ups, visitable< Character >::charges_of(), debugmsg, flag_BIONIC_ARMOR_INTERFACE, flag_USE_UPS(), units::from_kilojoule(), get_power_level(), has_active_bionic(), item::has_flag(), has_power(), is_mounted(), itype_adv_UPS_off, itype_bio_armor, itype_fire, itype_toolset, itype_UPS, itype_UPS_off, MF_RIDEABLE_MECH, mod_power_level(), mounted_creature, my_bionics, pos(), visitable< Character >::remove_item(), SKIP, units::to_kilojoule(), item::typeId(), item::use_charges(), use_charges(), use_fire(), and visitable< Character >::visit_items().

Referenced by iexamine::arcfurnace_empty(), consume_charges(), player::consume_items(), consume_med(), consume_remote_fuel(), player::consume_tools(), eat(), iuse::ecig(), iexamine::fertilize_plant(), ranged::fire_gun(), iexamine::fireplace(), iexamine::fvat_empty(), activity_handlers::gunmod_add_finish(), hack_attempt(), iexamine::keg(), iexamine::kiln_empty(), monexamine::pay_bot(), iexamine::pay_gas(), activity_handlers::plant_seed_finish(), process_items(), iexamine::reload_furniture(), vehicle::reload_seeds(), talk_effect_fun_t::set_bulk_trade_accept(), talk_effect_fun_t::set_consume_item(), talk_effect_fun_t::set_u_sell_item(), smoker_activate(), npc_trading::transfer_items(), try_consume(), try_start_hacking(), consume_drug_iuse::use(), place_monster_iuse::use(), cauterize_actor::use(), use_charges(), use_charges_if_avail(), use_fire(), and iexamine::vending().

◆ use_charges_if_avail()

bool Character::use_charges_if_avail ( const itype_id it,
int  quantity 
)

Definition at line 9605 of file character.cpp.

9606{
9607 if( has_charges( it, quantity ) ) {
9608 use_charges( it, quantity );
9609 return true;
9610 }
9611 return false;
9612}

References has_charges(), and use_charges().

Referenced by iuse::arrow_flammable(), iuse::firecracker(), activity_handlers::game_do_turn(), iuse::meth(), iuse::note_bionics(), item::process_tool(), item::reload(), iuse::smoking(), suffer_from_asthma(), and iuse_transform::use().

◆ use_fire()

void Character::use_fire ( int  quantity)

Definition at line 9765 of file character.cpp.

9766{
9767 //Okay, so checks for nearby fires first,
9768 //then held lit torch or candle, bionic tool/lighter/laser
9769 //tries to use 1 charge of lighters, matches, flame throwers
9770 //If there is enough power, will use power of one activation of the bio_lighter, bio_tools and bio_laser
9771 // (home made, military), hotplate, welder in that order.
9772 // bio_lighter, bio_laser, bio_tools, has_active_bionic("bio_tools"
9773
9774 if( get_map().has_nearby_fire( pos() ) ) {
9775 return;
9776 } else if( has_item_with_flag( "FIRE" ) ) {
9777 return;
9778 } else if( has_item_with_flag( "FIRESTARTER" ) ) {
9779 auto firestarters = all_items_with_flag( "FIRESTARTER" );
9780 for( auto &i : firestarters ) {
9781 if( has_charges( i->typeId(), quantity ) ) {
9782 use_charges( i->typeId(), quantity );
9783 return;
9784 }
9785 }
9786 } else if( has_active_bionic( bio_tools ) && get_power_level() > quantity * 5_kJ ) {
9787 mod_power_level( -quantity * 5_kJ );
9788 return;
9789 } else if( has_bionic( bio_lighter ) && get_power_level() > quantity * 5_kJ ) {
9790 mod_power_level( -quantity * 5_kJ );
9791 return;
9792 } else if( has_bionic( bio_laser ) && get_power_level() > quantity * 5_kJ ) {
9793 mod_power_level( -quantity * 5_kJ );
9794 return;
9795 }
9796}

References all_items_with_flag(), bio_laser, bio_lighter, bio_tools, get_map(), get_power_level(), has_active_bionic(), has_bionic(), has_charges(), has_item_with_flag(), mod_power_level(), pos(), and use_charges().

Referenced by use_charges().

◆ used_weapon() [1/2]

item & Character::used_weapon ( )

Definition at line 143 of file melee.cpp.

144{
145 return const_cast<item &>( const_cast<const Character *>( this )->used_weapon() );
146}

References used_weapon().

◆ used_weapon() [2/2]

const item & Character::used_weapon ( ) const

Returns a reference to the item which will be used to make attacks.

At the moment it's always weapon or a reference to a null item.

Definition at line 138 of file melee.cpp.

139{
140 return martial_arts_data->selected_force_unarmed() ? null_item_reference() : weapon;
141}

References martial_arts_data, null_item_reference(), and weapon.

Referenced by get_melee_hit_base(), ma_requirements::is_valid_character(), melee_attack(), on_dodge(), unarmed_attack(), and used_weapon().

◆ valid_aoe_technique() [1/2]

bool Character::valid_aoe_technique ( Creature t,
const ma_technique technique 
)
private

Check if an area-of-effect technique has valid targets.

Definition at line 1220 of file melee.cpp.

1221{
1222 std::vector<Creature *> dummy_targets;
1223 return valid_aoe_technique( t, technique, dummy_targets );
1224}

References valid_aoe_technique().

Referenced by perform_technique(), pick_technique(), and valid_aoe_technique().

◆ valid_aoe_technique() [2/2]

bool Character::valid_aoe_technique ( Creature t,
const ma_technique technique,
std::vector< Creature * > &  targets 
)
private

Definition at line 1226 of file melee.cpp.

1228{
1229 if( technique.aoe.empty() ) {
1230 return false;
1231 }
1232
1233 // pre-computed matrix of adjacent squares
1234 std::array<int, 9> offset_a = { {0, -1, -1, 1, 0, -1, 1, 1, 0 } };
1235 std::array<int, 9> offset_b = { {-1, -1, 0, -1, 0, 1, 0, 1, 1 } };
1236
1237 // filter the values to be between -1 and 1 to avoid indexing the array out of bounds
1238 int dy = std::max( -1, std::min( 1, t.posy() - posy() ) );
1239 int dx = std::max( -1, std::min( 1, t.posx() - posx() ) );
1240 int lookup = dy + 1 + 3 * ( dx + 1 );
1241
1242 //wide hits all targets adjacent to the attacker and the target
1243 if( technique.aoe == "wide" ) {
1244 //check if either (or both) of the squares next to our target contain a possible victim
1245 //offsets are a pre-computed matrix allowing us to quickly lookup adjacent squares
1246 tripoint left = pos() + tripoint( offset_a[lookup], offset_b[lookup], 0 );
1247 tripoint right = pos() + tripoint( offset_b[lookup], -offset_a[lookup], 0 );
1248
1249 monster *const mon_l = g->critter_at<monster>( left );
1250 if( mon_l && mon_l->friendly == 0 ) {
1251 targets.push_back( mon_l );
1252 }
1253 monster *const mon_r = g->critter_at<monster>( right );
1254 if( mon_r && mon_r->friendly == 0 ) {
1255 targets.push_back( mon_r );
1256 }
1257
1258 npc *const npc_l = g->critter_at<npc>( left );
1259 npc *const npc_r = g->critter_at<npc>( right );
1260 if( npc_l && npc_l->is_enemy() ) {
1261 targets.push_back( npc_l );
1262 }
1263 if( npc_r && npc_r->is_enemy() ) {
1264 targets.push_back( npc_r );
1265 }
1266 if( !targets.empty() ) {
1267 return true;
1268 }
1269 }
1270
1271 if( technique.aoe == "impale" ) {
1272 // Impale hits the target and a single target behind them
1273 // Check if the square cardinally behind our target, or to the left / right,
1274 // contains a possible target.
1275 tripoint left = t.pos() + tripoint( offset_a[lookup], offset_b[lookup], 0 );
1276 tripoint target_pos = t.pos() + ( t.pos() - pos() );
1277 tripoint right = t.pos() + tripoint( offset_b[lookup], -offset_b[lookup], 0 );
1278
1279 monster *const mon_l = g->critter_at<monster>( left );
1280 monster *const mon_t = g->critter_at<monster>( target_pos );
1281 monster *const mon_r = g->critter_at<monster>( right );
1282 if( mon_l && mon_l->friendly == 0 ) {
1283 targets.push_back( mon_l );
1284 }
1285 if( mon_t && mon_t->friendly == 0 ) {
1286 targets.push_back( mon_t );
1287 }
1288 if( mon_r && mon_r->friendly == 0 ) {
1289 targets.push_back( mon_r );
1290 }
1291
1292 npc *const npc_l = g->critter_at<npc>( left );
1293 npc *const npc_t = g->critter_at<npc>( target_pos );
1294 npc *const npc_r = g->critter_at<npc>( right );
1295 if( npc_l && npc_l->is_enemy() ) {
1296 targets.push_back( npc_l );
1297 }
1298 if( npc_t && npc_t->is_enemy() ) {
1299 targets.push_back( npc_t );
1300 }
1301 if( npc_r && npc_r->is_enemy() ) {
1302 targets.push_back( npc_r );
1303 }
1304 if( !targets.empty() ) {
1305 return true;
1306 }
1307 }
1308
1309 if( targets.empty() && technique.aoe == "spin" ) {
1310 for( const tripoint &tmp : g->m.points_in_radius( pos(), 1 ) ) {
1311 if( tmp == t.pos() ) {
1312 continue;
1313 }
1314 monster *const mon = g->critter_at<monster>( tmp );
1315 if( mon && mon->friendly == 0 ) {
1316 targets.push_back( mon );
1317 }
1318 npc *const np = g->critter_at<npc>( tmp );
1319 if( np && np->is_enemy() ) {
1320 targets.push_back( np );
1321 }
1322 }
1323 //don't trigger circle for fewer than 2 targets
1324 if( targets.size() < 2 ) {
1325 targets.clear();
1326 } else {
1327 return true;
1328 }
1329 }
1330 return false;
1331}
bool is_enemy() const
Definition: npc.cpp:2059

References ma_technique::aoe, monster::friendly, g, npc::is_enemy(), left, Creature::pos(), pos(), Creature::posx(), posx(), Creature::posy(), posy(), and right.

◆ visibility()

int Character::visibility ( bool  check_color = false,
int  stillness = 0 
) const

Checks is_invisible() as well as other factors.

Definition at line 6254 of file character.cpp.

6255{
6256 // 0-100 %
6257 if( is_invisible() ) {
6258 return 0;
6259 }
6260 // TODO:
6261 // if ( dark_clothing() && light check ...
6262 int stealth_modifier = std::floor( mutation_value( "stealth_modifier" ) );
6263 return clamp( 100 - stealth_modifier, 40, 160 );
6264}
bool is_invisible() const
Definition: character.cpp:6244

References clamp(), is_invisible(), and mutation_value().

◆ visible_mutations()

std::string Character::visible_mutations ( int  visibility_cap) const

Returns an enumeration of visible mutations with colors.

Definition at line 1743 of file mutation.cpp.

1744{
1745 const std::vector<trait_id> &my_muts = get_mutations();
1746 const std::string trait_str = enumerate_as_string( my_muts.begin(), my_muts.end(),
1747 [visibility_cap ]( const trait_id & pr ) -> std::string {
1748 const auto &mut_branch = pr.obj();
1749 // Finally some use for visibility trait of mutations
1750 if( mut_branch.visibility > 0 && mut_branch.visibility >= visibility_cap )
1751 {
1752 return colorize( mut_branch.name(), mut_branch.get_display_color() );
1753 }
1754
1755 return std::string();
1756 } );
1757 return trait_str;
1758}

References enumerate_as_string(), and get_mutations().

Referenced by npc::print_info(), and short_description_parts().

◆ vitamin_get()

int Character::vitamin_get ( const vitamin_id vit) const

Check current level of a vitamin.

Accesses level of a given vitamin. If the vitamin_id specified does not exist then this function simply returns 0.

Parameters
vitID of vitamin to check level for.
Returns
current level for specified vitamin

Definition at line 580 of file consumption.cpp.

581{
582 if( get_option<bool>( "NO_VITAMINS" ) && vit->type() == vitamin_type::VITAMIN ) {
583 return 0;
584 }
585
586 const auto &v = vitamin_levels.find( vit );
587 return v != vitamin_levels.end() ? v->second : 0;
588}
const vitamin_type & type() const
Definition: vitamin.h:40
@ VITAMIN
Definition: vitamin.h:19

References vitamin::type(), VITAMIN, and vitamin_levels.

Referenced by debug_menu::character_edit_menu(), eff_fun_mutating(), and update_vitamins().

◆ vitamin_mod()

int Character::vitamin_mod ( const vitamin_id vit,
int  qty,
bool  capped = true 
)

Add or subtract vitamins from character storage pools.

Parameters
vitID of vitamin to modify
qtyamount by which to adjust vitamin (negative values are permitted)
cappedif true prevent vitamins which can accumulate in excess from doing so
Returns
adjusted level for the vitamin or zero if vitamin does not exist

Definition at line 548 of file consumption.cpp.

549{
550 if( !vit.is_valid() ) {
551 debugmsg( "Vitamin with id %s does not exist, and cannot be modified", vit.str() );
552 return 0;
553 }
554 // What's going on here? Emplace returns either an iterator to the inserted
555 // item or, if it already exists, an iterator to the (unchanged) extant item
556 // (Okay, technically it returns a pair<iterator, bool>, the iterator is what we want)
557 auto it = vitamin_levels.emplace( vit, 0 ).first;
558 const vitamin &v = *it->first;
559
560 if( qty > 0 ) {
561 // Accumulations can never occur from food sources
562 it->second = std::min( it->second + qty, capped ? 0 : v.max() );
563 update_vitamins( vit );
564
565 } else if( qty < 0 ) {
566 it->second = std::max( it->second + qty, v.min() );
567 update_vitamins( vit );
568 }
569
570 return it->second;
571}
void update_vitamins(const vitamin_id &vit)
Set vitamin deficiency/excess disease states dependent upon current vitamin levels.
Definition: character.cpp:8756
int max() const
Upper bound for any accumulation of this vitamin.
Definition: vitamin.h:72
int min() const
Lower bound for deficiency of this vitamin.
Definition: vitamin.h:67

References debugmsg, string_id< T >::is_valid(), vitamin::max(), vitamin::min(), string_id< T >::str(), update_vitamins(), and vitamin_levels.

Referenced by eff_fun_bleed(), rooted(), suffer_from_other_mutations(), suffer_in_sunlight(), update_body(), consume_drug_iuse::use(), vitamin_set(), and vitamins_mod().

◆ vitamin_rate()

time_duration Character::vitamin_rate ( const vitamin_id vit) const

Get vitamin usage rate (minutes per unit) accounting for bionics, mutations and effects.

Definition at line 533 of file consumption.cpp.

534{
535 time_duration res = vit.obj().rate();
536
537 for( const auto &m : get_mutations() ) {
538 const auto &mut = m.obj();
539 auto iter = mut.vitamin_rates.find( vit );
540 if( iter != mut.vitamin_rates.end() ) {
541 res += iter->second;
542 }
543 }
544
545 return res;
546}
time_duration rate() const
Usage rate of vitamin (time to consume unit) Lower bound is zero whereby vitamin is not required (but...
Definition: vitamin.h:80

References get_mutations(), string_id< T >::obj(), and vitamin::rate().

Referenced by item::food_info(), update_body(), and consume_drug_iuse::use().

◆ vitamin_set()

bool Character::vitamin_set ( const vitamin_id vit,
int  qty 
)

Sets level of a vitamin or returns false if id given in vit does not exist.

Note
status effects are still set for deficiency/excess
Parameters
[in]vitID of vitamin to adjust quantity for
[in]qtyQuantity to set level to
Returns
false if given vitamin_id does not exist, otherwise true

Definition at line 590 of file consumption.cpp.

591{
592 auto v = vitamin_levels.find( vit );
593 if( v == vitamin_levels.end() ) {
594 return false;
595 }
596 vitamin_mod( vit, qty - v->second, false );
597
598 return true;
599}

References vitamin_levels, and vitamin_mod().

Referenced by debug_menu::character_edit_menu(), eff_fun_mutating(), and eff_fun_toxin_buildup().

◆ vitamins_mod()

void Character::vitamins_mod ( const std::map< vitamin_id, int > &  vitamins,
bool  capped = true 
)

Definition at line 573 of file consumption.cpp.

574{
575 for( auto vit : vitamins ) {
576 vitamin_mod( vit.first, vit.second, capped );
577 }
578}

References vitamin_mod().

Referenced by update_stomach().

◆ volume_capacity()

◆ volume_capacity_reduced_by()

units::volume Character::volume_capacity_reduced_by ( const units::volume mod,
const excluded_stacks without = {} 
) const

Definition at line 2644 of file character.cpp.

2646{
2648 return units::volume_max;
2649 }
2650
2652 for( const auto &i : worn ) {
2653 if( !without.count( &i ) ) {
2654 ret += i.get_storage();
2655 }
2656 }
2657 if( has_bionic( bio_storage ) ) {
2658 ret += 2_liter;
2659 }
2660 if( has_trait( trait_SHELL ) ) {
2661 ret += 4_liter;
2662 }
2664 ret += 6_liter;
2665 }
2666 if( has_trait( trait_PACKMULE ) ) {
2667 ret = ret * 1.4;
2668 }
2669 if( has_trait( trait_DISORGANIZED ) ) {
2670 ret = ret * 0.6;
2671 }
2672 return std::max( ret, 0_ml );
2673}
static const trait_id trait_SHELL("SHELL")
static const trait_id trait_DISORGANIZED("DISORGANIZED")
static const trait_id trait_PACKMULE("PACKMULE")
static const bionic_id bio_storage("bio_storage")
const volume volume_max
Definition: units_volume.h:21

References bio_storage, has_active_mutation(), has_bionic(), has_trait(), cata::hash64_detail::ret, trait_DEBUG_STORAGE, trait_DISORGANIZED, trait_PACKMULE, trait_SHELL, trait_SHELL2, units::volume_max, and worn.

Referenced by inventory_drop_selector::get_raw_stats(), pickup::reorder_for_dropping(), takeoff(), and volume_capacity().

◆ volume_carried()

◆ volume_carried_reduced_by()

units::volume Character::volume_carried_reduced_by ( const excluded_stacks without) const

Definition at line 2586 of file character.cpp.

2587{
2588 if( without.empty() ) {
2589 return inv.volume();
2590 } else {
2591 return inv.volume_without( without );
2592 }
2593}
units::volume volume_without(const excluded_stacks &without) const
Definition: inventory.cpp:1071

References inv, inventory::volume(), and inventory::volume_without().

Referenced by inventory_drop_selector::get_raw_stats().

◆ vomit()

void Character::vomit ( )

Handles Character vomiting effects.

Definition at line 7654 of file character.cpp.

7655{
7656 g->events().send<event_type::throws_up>( getID() );
7657
7658 map &here = get_map();
7659 if( get_effect_int( effect_fungus ) >= 3 ) {
7660 add_msg_player_or_npc( m_bad, _( "You vomit thousands of live spores!" ),
7661 _( "<npcname> vomits thousands of live spores!" ) );
7662 fungal_effects( *g, here ).fungalize( pos(), this );
7663 } else if( stomach.get_calories() > 0 || get_thirst() < 0 ) {
7664 add_msg_player_or_npc( m_bad, _( "You throw up heavily!" ), _( "<npcname> throws up heavily!" ) );
7665 here.add_field( character_funcs::pick_safe_adjacent_tile( *this ).value_or( pos() ), fd_bile, 1 );
7666 } else {
7667 return;
7668 }
7669
7670 if( !has_effect( effect_nausea ) ) { // Prevents never-ending nausea
7671 const effect dummy_nausea( &effect_nausea.obj(), 0_turns, bodypart_str_id::NULL_ID(), 1,
7673 add_effect( effect_nausea, std::max( dummy_nausea.get_max_duration() *
7674 stomach.get_calories() / 100, dummy_nausea.get_int_dur_factor() ) );
7675 }
7676
7677 stomach.empty();
7678 set_thirst( std::max( 0, get_thirst() ) );
7680 if( get_healthy_mod() > 0 ) {
7681 set_healthy_mod( 0 );
7682 }
7683
7684 moves -= 100;
7685 // get_effect is more correct than has_effect because of body parts
7686 effect &eff_foodpoison = get_effect( effect_foodpoison );
7687 if( eff_foodpoison ) {
7688 eff_foodpoison.mod_duration( -30_minutes );
7689 }
7690 effect &eff_drunk = get_effect( effect_drunk );
7691 if( eff_drunk ) {
7692 eff_drunk.mod_duration( rng( -10_minutes, -50_minutes ) );
7693 }
7697 // Don't wake up when just retching
7698 wake_up();
7699}
static const efftype_id effect_fungus("fungus")
static const efftype_id effect_pkill2("pkill2")
static const efftype_id effect_bloated("bloated")
static const efftype_id effect_foodpoison("foodpoison")
static const efftype_id effect_pkill1("pkill1")
static const efftype_id effect_pkill3("pkill3")
void fungalize(const tripoint &p, Creature *origin=nullptr, double spore_chance=0.0)
field_type_id fd_bile
Definition: field_type.cpp:337
cata::optional< tripoint > pick_safe_adjacent_tile(const Character &who)
Returns an unoccupied, safe adjacent point.

References _, Creature::add_effect(), Creature::add_msg_player_or_npc(), effect_bloated, effect_drunk, effect_foodpoison, effect_fungus, effect_nausea, effect_pkill1, effect_pkill2, effect_pkill3, stomach_contents::empty(), fd_bile, fungal_effects::fungalize(), g, stomach_contents::get_calories(), Creature::get_effect(), Creature::get_effect_int(), get_healthy_mod(), effect::get_int_dur_factor(), get_map(), effect::get_max_duration(), get_thirst(), getID(), Creature::has_effect(), m_bad, effect::mod_duration(), Creature::moves, string_id< body_part_type >::NULL_ID(), string_id< T >::obj(), character_funcs::pick_safe_adjacent_tile(), pos(), Creature::remove_effect(), rng(), set_healthy_mod(), set_thirst(), stomach, throws_up, calendar::turn, and wake_up().

Referenced by activate_mutation(), addict_effect(), iuse::artifact(), iuse::blech(), iuse::dig(), eat(), eff_fun_hallu(), eff_fun_hot(), eff_fun_rat(), hardcoded_effects(), marloss_common(), iuse::mycus(), process_effects_internal(), process_one_effect(), iuse::sewage(), suffer_from_radiation(), suffer_while_awake(), try_reject_mutagen(), avatar::vomit(), and spell_effect::vomit().

◆ wait_effects()

void Character::wait_effects ( )

Definition at line 1507 of file character.cpp.

1508{
1509 if( has_effect( effect_downed ) ) {
1510 try_remove_downed( *this );
1511 return;
1512 }
1513 if( has_effect( effect_beartrap ) ) {
1514 try_remove_bear_trap( *this );
1515 return;
1516 }
1517 if( has_effect( effect_lightsnare ) ) {
1518 try_remove_lightsnare( *this );
1519 return;
1520 }
1521 if( has_effect( effect_heavysnare ) ) {
1522 try_remove_heavysnare( *this );
1523 return;
1524 }
1525 if( has_effect( effect_webbed ) ) {
1526 try_remove_webs( *this );
1527 return;
1528 }
1529 if( has_effect( effect_grabbed ) ) {
1530 try_remove_grab( *this );
1531 return;
1532 }
1533}

References effect_beartrap, effect_downed, effect_grabbed, effect_heavysnare, effect_lightsnare, effect_webbed, Creature::has_effect(), try_remove_bear_trap(), try_remove_downed(), try_remove_grab(), try_remove_heavysnare(), try_remove_lightsnare(), and try_remove_webs().

Referenced by character_funcs::do_pause().

◆ wake_up()

void Character::wake_up ( )

Removes "sleep" and "lying_down".

Definition at line 7533 of file character.cpp.

7534{
7538 if( has_effect( effect_sleep ) ) {
7539 g->events().send<event_type::character_wakes_up>( getID() );
7541 // Wake up might be called more than once per turn, but we only need to recalc after removing sleep
7543 }
7544}
static const efftype_id effect_slept_through_alarm("slept_through_alarm")
static const efftype_id effect_alarm_clock("alarm_clock")
@ character_wakes_up

References character_wakes_up, effect_alarm_clock, effect_lying_down, effect_sleep, effect_slept_through_alarm, g, getID(), Creature::has_effect(), recalc_sight_limits(), and Creature::remove_effect().

Referenced by hardcoded_effects(), on_hurt(), sounds::process_sound_markers(), react_to_felt_pain(), Creature::remove_effect(), suffer_from_asthma(), suffer_from_sunburn(), update_bodytemp(), vomit(), and avatar::wake_up().

◆ warmth()

std::map< bodypart_id, int > Character::warmth ( const std::map< bodypart_id, std::vector< const item * > > &  clothing_map) const

Returns warmth provided by armor, etc.

Definition at line 9328 of file character.cpp.

9330{
9331 std::map<bodypart_id, int> ret;
9332 for( const bodypart_id &bp : get_all_body_parts() ) {
9333 ret.emplace( bp, 0 );
9334 }
9335
9336 for( const std::pair<const bodypart_id, std::vector<const item *>> &on_bp : clothing_map ) {
9337 const bodypart_id &bp = on_bp.first;
9338 for( const item *it : on_bp.second ) {
9339 double warmth = it->get_warmth();
9340 // Warmth reduced linearly with wetness
9341 const auto &materials = it->made_of();
9342 float max_wet_resistance = std::accumulate( materials.begin(), materials.end(), 0.0f,
9343 []( float best, const material_id & mat ) {
9344 return std::max( best, mat->warmth_when_wet() );
9345 } );
9346 float wet_mult = 1.0f - max_wet_resistance * body_wetness[bp->token] / drench_capacity[bp->token];
9347 ret[bp] += warmth * wet_mult;
9348 }
9349 ret[bp] += get_effect_int( effect_heating_bionic, bp->token );
9350 }
9351 return ret;
9352}
static const efftype_id effect_heating_bionic("heating_bionic")
int get_warmth() const
Returns the warmth value that this item has when worn.
Definition: item.cpp:5923

References body_wetness, drench_capacity, effect_heating_bionic, Creature::get_all_body_parts(), Creature::get_effect_int(), item::get_warmth(), item::made_of(), and cata::hash64_detail::ret.

Referenced by weather_effect::wet_player().

◆ wear_item()

cata::optional< std::list< item >::iterator > Character::wear_item ( const item to_wear,
bool  interactive = true 
)

Wear a copy of specified item.

Parameters
to_wearItem to wear
interactiveIf set, won't alert the player or drain moves on completion
Returns
nullopt on fail, pointer to newly worn item on success.

Definition at line 2100 of file character.cpp.

2101{
2102 const auto ret = can_wear( to_wear );
2103 if( !ret.success() ) {
2104 if( interactive ) {
2105 add_msg_if_player( m_info, "%s", ret.c_str() );
2106 }
2107 return cata::nullopt;
2108 }
2109
2110 const bool was_deaf = is_deaf();
2111 const bool supertinymouse = get_size() == MS_TINY;
2112 last_item = to_wear.typeId();
2113
2114 std::list<item>::iterator position = position_to_wear_new_item( to_wear );
2115 std::list<item>::iterator new_item_it = worn.insert( position, to_wear );
2116
2117 if( interactive ) {
2119 _( "You put on your %s." ),
2120 _( "<npcname> puts on their %s." ),
2121 to_wear.tname() );
2122 moves -= item_wear_cost( to_wear );
2123
2124 for( const body_part bp : all_body_parts ) {
2125 if( to_wear.covers( bp ) && encumb( bp ) >= 40 ) {
2127 bp == bp_eyes ?
2128 _( "Your %s are very encumbered! %s" ) : _( "Your %s is very encumbered! %s" ),
2129 body_part_name( bp ), encumb_text( bp ) );
2130 }
2131 }
2132 if( !was_deaf && is_deaf() ) {
2133 add_msg_if_player( m_info, _( "You're deafened!" ) );
2134 }
2135 if( supertinymouse && !to_wear.has_flag( flag_UNDERSIZE ) ) {
2137 _( "This %s is too big to wear comfortably! Maybe it could be refitted." ),
2138 to_wear.tname() );
2139 } else if( !supertinymouse && to_wear.has_flag( flag_UNDERSIZE ) ) {
2141 _( "This %s is too small to wear comfortably! Maybe it could be refitted." ),
2142 to_wear.tname() );
2143 }
2144 } else {
2145 add_msg_if_npc( _( "<npcname> puts on their %s." ), to_wear.tname() );
2146 }
2147
2148 new_item_it->on_wear( *this );
2149
2150 inv.update_invlet( *new_item_it );
2151 inv.update_cache_with_item( *new_item_it );
2152
2155
2156 return new_item_it;
2157}
std::string encumb_text(body_part bp)
Returns the matching encumbrance text for a given body_part token.
Definition: bodypart.cpp:358
static const std::string flag_UNDERSIZE("UNDERSIZE")
void update_invlet(item &it, bool assign_invlet=true)
Definition: inventory.cpp:1217
void update_cache_with_item(item &newit)
Definition: inventory.cpp:253

References _, Creature::add_msg_if_npc(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), all_body_parts, body_part_name(), bp_eyes, can_wear(), item::covers(), encumb(), encumb_text(), flag_UNDERSIZE(), get_size(), item::has_flag(), inv, is_deaf(), item_wear_cost(), last_item, m_info, m_warning, Creature::moves, MS_TINY, cata::nullopt, position, position_to_wear_new_item(), recalc_sight_limits(), reset_encumbrance(), cata::hash64_detail::ret, item::tname(), item::typeId(), inventory::update_cache_with_item(), inventory::update_invlet(), and worn.

Referenced by activity_on_turn_wear(), iexamine::autodoc(), avatar::create(), dispose_item(), pick_one_up(), spell_effect::spawn_ethereal_item(), standard_npc::standard_npc(), npc::stow_item(), avatar_funcs::use_item(), npc::wear_if_wanted(), and wear_possessed().

◆ wear_possessed()

cata::optional< std::list< item >::iterator > Character::wear_possessed ( item to_wear,
bool  interactive = true 
)

Wear specified item.

Item must be in characters possession (wielded or stored).

Parameters
to_wearItem to wear
interactiveIf set, won't alert the player or drain moves on completion
Returns
nullopt on fail, pointer to newly worn item on success

Definition at line 2944 of file character.cpp.

2945{
2946 if( is_worn( to_wear ) ) {
2947 if( interactive ) {
2949 _( "You are already wearing that." ),
2950 _( "<npcname> is already wearing that." )
2951 );
2952 }
2953 return cata::nullopt;
2954 }
2955 if( to_wear.is_null() ) {
2956 if( interactive ) {
2958 _( "You don't have that item." ),
2959 _( "<npcname> doesn't have that item." ) );
2960 }
2961 return cata::nullopt;
2962 }
2963
2964 bool was_weapon;
2965 item to_wear_copy( to_wear );
2966 if( &to_wear == &weapon ) {
2967 weapon = item();
2968 was_weapon = true;
2969 } else {
2970 inv.remove_item( &to_wear );
2971 inv.restack( *this->as_player() );
2972 was_weapon = false;
2973 }
2974
2975 auto result = wear_item( to_wear_copy, interactive );
2976 if( !result ) {
2977 if( was_weapon ) {
2978 weapon = to_wear_copy;
2979 } else {
2980 inv.add_item( to_wear_copy, true );
2981 }
2982 return cata::nullopt;
2983 }
2984
2985 return result;
2986}

References _, inventory::add_item(), Creature::add_msg_player_or_npc(), Creature::as_player(), inv, item::is_null(), is_worn(), m_info, cata::nullopt, inventory::remove_item(), inventory::restack(), weapon, and wear_item().

Referenced by examine_item_menu::run(), show_armor_layers_ui(), and wear().

◆ wearing_something_on()

bool Character::wearing_something_on ( const bodypart_id bp) const

Returns true if the character is wearing something on the entered body part.

Definition at line 8815 of file character.cpp.

8816{
8817 for( auto &i : worn ) {
8818 if( i.covers( bp->token ) ) {
8819 return true;
8820 }
8821 }
8822 return false;
8823}

References worn.

Referenced by armwear_factor(), can_drink_nectar(), can_wear(), iexamine::chainfence(), footwear_factor(), on_hit(), reset_stats(), suffer_from_sunburn(), and suffer_in_sunlight().

◆ weight_capacity()

units::mass Character::weight_capacity ( ) const
overridevirtual
Strength increases carrying capacity

Reimplemented from Creature.

Definition at line 2595 of file character.cpp.

2596{
2598 // Infinite enough
2599 return units::mass_max;
2600 }
2601 // Get base capacity from creature,
2602 // then apply player-only mutation and trait effects.
2604 /** @EFFECT_STR increases carrying capacity */
2605 ret += get_str() * 4_kilogram;
2606 ret *= mutation_value( "weight_capacity_modifier" );
2607
2608 units::mass worn_weight_bonus = 0_gram;
2609 for( const item &it : worn ) {
2610 ret *= it.get_weight_capacity_modifier();
2611 worn_weight_bonus += it.get_weight_capacity_bonus();
2612 }
2613
2614 units::mass bio_weight_bonus = 0_gram;
2615 for( const bionic_id &bid : get_bionics() ) {
2616 ret *= bid->weight_capacity_modifier;
2617 bio_weight_bonus += bid->weight_capacity_bonus;
2618 }
2619
2620 ret += bio_weight_bonus + worn_weight_bonus;
2621
2623 ret += 22500_gram;
2624 }
2625
2626 if( ret < 0_gram ) {
2627 ret = 0_gram;
2628 }
2629 if( is_mounted() ) {
2630 auto *mons = mounted_creature.get();
2631 // the mech has an effective strength for other purposes, like hitting.
2632 // but for lifting, its effective strength is even higher, due to its sturdy construction, leverage,
2633 // and being built entirely for that purpose with hydraulics etc.
2634 ret = mons->mech_str_addition() == 0 ? ret : ( mons->mech_str_addition() + 10 ) * 4_kilogram;
2635 }
2636 return ret;
2637}
virtual units::mass weight_capacity() const
Definition: creature.cpp:1780
@ AEP_CARRY_MORE
Definition: enums.h:118

References AEP_CARRY_MORE, get_bionics(), get_str(), has_artifact_with(), has_trait(), is_mounted(), units::mass_max, mounted_creature, mutation_value(), cata::hash64_detail::ret, trait_DEBUG_STORAGE, Creature::weight_capacity(), and worn.

Referenced by activate_bionic(), are_requirements_nearby(), burn_move_stamina(), can_pick_weight(), carry_weight_string(), pickup::cost_to_move_item(), overmap_ui::display(), pickup::do_pickup(), draw_speed_tab(), draw_stats_info(), draw_weightvolume_labels(), npc::drop_items(), fetch_activity(), find_best_bench(), npc::find_item(), inventory_selector::get_raw_stats(), inventory_drop_selector::get_raw_stats(), iexamine::ledge(), npc_pickup_from_stack(), trading_window::perform_trade(), recalc_speed_bonus(), set_stats(), suffer_while_awake(), and weight_carried_reduced_by().

◆ weight_carried()

◆ weight_carried_reduced_by()

units::mass Character::weight_carried_reduced_by ( const excluded_stacks without) const

Definition at line 2538 of file character.cpp.

2539{
2540 const std::map<const item *, int> empty;
2541
2542 // Worn items
2543 units::mass ret = 0_gram;
2544 for( auto &i : worn ) {
2545 if( !without.count( &i ) ) {
2546 ret += i.weight();
2547 }
2548 }
2549
2550 // Items in inventory
2551 ret += inv.weight_without( without );
2552
2553 // Wielded item
2554 units::mass weaponweight = 0_gram;
2555 auto weapon_it = without.find( &weapon );
2556 if( weapon_it == without.end() ) {
2557 weaponweight = weapon.weight();
2558 } else {
2559 int subtract_count = ( *weapon_it ).second;
2560 if( weapon.count_by_charges() ) {
2561 item copy = weapon;
2562 copy.charges -= subtract_count;
2563 if( copy.charges < 0 ) {
2564 debugmsg( "Trying to remove more charges than the wielded item has" );
2565 copy.charges = 0;
2566 }
2567 weaponweight = copy.weight();
2568 } else if( subtract_count > 1 ) {
2569 debugmsg( "Trying to remove more than one wielded item" );
2570 }
2571 }
2572 // Exclude wielded item if using lifting tool
2573 if( weaponweight + ret > weight_capacity() ) {
2574 const float liftrequirement = std::ceil( units::to_gram<float>( weaponweight ) /
2575 units::to_gram<float>( TOOL_LIFT_FACTOR ) );
2576 if( g->new_game || best_nearby_lifting_assist() < liftrequirement ) {
2577 ret += weaponweight;
2578 }
2579 } else {
2580 ret += weaponweight;
2581 }
2582
2583 return ret;
2584}
units::mass weight_without(const excluded_stacks &without) const
Definition: inventory.cpp:1042
#define TOOL_LIFT_FACTOR

References best_nearby_lifting_assist(), item::charges, item::count_by_charges(), debugmsg, g, inv, cata::hash64_detail::ret, TOOL_LIFT_FACTOR, weapon, item::weight(), weight_capacity(), inventory::weight_without(), and worn.

Referenced by inventory_drop_selector::get_raw_stats(), and weight_carried().

◆ wield()

virtual bool Character::wield ( item target)
pure virtual

Removes currently wielded item (if any) and replaces it with the target item.

Parameters
targetreplacement item to wield or null item to remove existing weapon without replacing it
Returns
whether both removal and replacement were successful (they are performed atomically)

Implemented in npc, and avatar.

Referenced by handle_melee_wear(), mount_creature(), perform_technique(), pick_one_up(), and mattack::riotbot().

◆ will_eat()

ret_val< edible_rating > Character::will_eat ( const item food,
bool  interactive = false 
) const

Same as can_eat, but takes consequences into account.

Asks about them if

Parameters
interactiveis true, refuses otherwise.

Definition at line 732 of file consumption.cpp.

733{
734 const auto ret = can_eat( food );
735 if( !ret.success() ) {
736 if( interactive ) {
737 add_msg_if_player( m_info, "%s", ret.c_str() );
738 }
739 return ret;
740 }
741
742 std::vector<ret_val<edible_rating>> consequences;
743 const auto add_consequence = [&consequences]( const std::string & msg, edible_rating code ) {
744 consequences.emplace_back( ret_val<edible_rating>::make_failure( code, msg ) );
745 };
746
747 const bool saprophage = has_trait( trait_SAPROPHAGE );
748 const auto &comest = food.get_comestible();
749
750 if( food.rotten() ) {
751 const bool saprovore = has_trait( trait_SAPROVORE );
752 if( !saprophage && !saprovore && !has_bionic( bio_digestion ) ) {
753 add_consequence( _( "This is rotten and smells awful!" ), edible_rating::rotten );
754 }
755 }
756
757 const bool carnivore = has_trait( trait_CARNIVORE );
758 if( food.has_flag( flag_CANNIBALISM ) && !has_trait_flag( "CANNIBAL" ) ) {
759 add_consequence( _( "The thought of eating human flesh makes you feel sick." ),
761 }
762
763 const bool edible = comest->comesttype == comesttype_FOOD || food.has_flag( flag_USE_EAT_VERB );
764
765 int food_kcal = compute_effective_nutrients( food ).kcal;
766 if( food_kcal > 0 && has_effect( effect_nausea ) ) {
767 add_consequence( _( "You still feel nauseous and will probably puke it all up again." ),
769 }
770
771 if( ( food_kcal > 0 || comest->quench > 0 ) && has_effect( effect_bloated )
772 && !food.has_flag( flag_NO_BLOAT ) ) {
773 add_consequence( _( "You're full and will vomit if you try to consume anything." ),
775 }
776
777 if( ( allergy_type( food ) != MORALE_NULL ) || ( carnivore && food.has_flag( flag_ALLERGEN_JUNK ) &&
778 !food.has_flag( flag_CARNIVORE_OK ) ) ) {
779 add_consequence( _( "Your stomach won't be happy (allergy)." ), edible_rating::allergy );
780 }
781
782 if( saprophage && edible && food.rotten() && !food.has_flag( flag_FERTILIZER ) ) {
783 // Note: We're allowing all non-solid "food". This includes drugs
784 // Hard-coding fertilizer for now - should be a separate flag later
785 //~ No, we don't eat "rotten" food. We eat properly aged food, like a normal person.
786 //~ Semantic difference, but greatly facilitates people being proud of their character.
787 add_consequence( _( "Your stomach won't be happy (not rotten enough)." ),
789 }
790
791 if( !food.has_infinite_charges() &&
792 ( ( food_kcal > 0 &&
793 get_stored_kcal() + stomach.get_calories() + food_kcal
794 > max_stored_kcal() ) ||
795 ( comest->quench > 0 && get_thirst() < comest->quench ) ) ) {
796 add_consequence( _( "You're full already and the excess food will be wasted." ),
798 }
799
800 if( !consequences.empty() ) {
801 if( !interactive ) {
802 return consequences.front();
803 }
804 std::string req;
805 for( const auto &elem : consequences ) {
806 req += elem.str() + "\n";
807 }
808
809 const bool eat_verb = food.has_flag( flag_USE_EAT_VERB );
810 std::string food_tname = food.tname();
811 const nc_color food_color = food.color_in_inventory();
812 if( eat_verb || comest->comesttype == comesttype_FOOD ) {
813 req += string_format( _( "Eat your %s anyway?" ), colorize( food_tname, food_color ) );
814 } else if( !eat_verb && comest->comesttype == comesttype_DRINK ) {
815 req += string_format( _( "Drink your %s anyway?" ), colorize( food_tname, food_color ) );
816 } else {
817 req += string_format( _( "Consume your %s anyway?" ), colorize( food_tname, food_color ) );
818 }
819
820 if( !query_yn( req ) ) {
821 return consequences.front();
822 }
823 }
824 // All checks ended, it's edible (or we're pretending it is)
826}
edible_rating
Definition: character.h:156
bool has_infinite_charges() const
Definition: item.cpp:9961
The class represents a composite return value of an arbitrary function (result).
Definition: ret_val.h:21
static const std::string flag_FERTILIZER("FERTILIZER")
static const efftype_id effect_nausea("nausea")

References _, Creature::add_msg_if_player(), allergy, allergy_type(), allergy_weak, bio_digestion, bloated, can_eat(), cannibalism, item::color_in_inventory(), colorize(), comesttype_DRINK(), comesttype_FOOD(), compute_effective_nutrients(), edible, effect_bloated, effect_nausea, flag_ALLERGEN_JUNK(), flag_CANNIBALISM(), flag_CARNIVORE_OK(), flag_FERTILIZER(), flag_NO_BLOAT(), flag_USE_EAT_VERB(), stomach_contents::get_calories(), item::get_comestible(), get_stored_kcal(), get_thirst(), has_bionic(), Creature::has_effect(), item::has_flag(), item::has_infinite_charges(), has_trait(), has_trait_flag(), nutrients::kcal, m_info, ret_val< T >::make_success(), max_stored_kcal(), MORALE_NULL, nausea, query_yn(), cata::hash64_detail::ret, rotten, item::rotten(), stomach, string_format(), item::tname(), too_full, trait_CARNIVORE, trait_SAPROPHAGE, and trait_SAPROVORE.

Referenced by item::color_in_inventory(), npc::consume_food(), eat(), find_auto_consume(), examine_item_menu::rate_action_eat(), and npc::value().

◆ worn_position_to_index()

static int Character::worn_position_to_index ( int  position)
inlinestatic

Definition at line 1081 of file character.h.

1081 {
1082 return -2 - position;
1083 }

References position.

Referenced by advanced_inventory::action_examine(), get_item_position(), i_at(), i_rem(), and avatar_action::wield().

◆ worn_with_flag()

Member Data Documentation

◆ _skills

◆ activity

player_activity Character::activity

Definition at line 1541 of file character.h.

Referenced by activate_mutation(), activity_on_turn_move_loot(), assign_activity(), assign_stashed_activity(), iexamine::autodoc(), activity_handlers::build_do_turn(), iuse::burrow(), game::butcher(), butcher_corpse_activity(), character_effects::calc_focus_equilibrium(), cancel_activity(), game::cancel_activity_or_ignore_query(), game::cancel_activity_query(), check_outbounds_activity(), iuse::chop_logs(), chop_plank_activity(), iuse::chop_tree(), chop_tree_activity(), iuse::clear_rubble(), complete_construction(), veh_interact::complete_vehicle(), construction_activity(), iuse::craft(), iuse::cut_log_into_planks(), npc::do_player_activity(), npc::do_pulp(), avatar::do_read(), game::do_turn(), player_activity::do_turn(), pickup_activity_actor::do_turn(), npc::drop(), eff_fun_bleed(), fall_asleep(), fetch_activity(), iuse::fill_pit(), activity_handlers::find_mount_do_turn(), npc::finish_read(), iuse::fishing_rod(), game::forced_door_closing(), generic_multi_activity_check_requirement(), generic_multi_activity_do(), generic_multi_activity_handler(), player_activity::get_progress_message(), talk_function::give_aid(), talk_function::give_all_aid(), avatar_funcs::gunmod_add(), iuse::hacksaw(), iuse::hand_crank(), game::handle_key_blocking_activity(), hardcoded_effects(), has_activity(), npc::has_player_activity(), in_sleep_state(), install_bionics(), vehicle::interact_with(), inv_internal(), iuse::jackhammer(), load(), npc::load(), iuse::makemound(), monexamine::milk_source(), mine_activity(), npc::move(), map::move_vehicle(), npc::on_load(), iuse::oxytorch(), perform_zone_activity_turn(), iuse::pickaxe(), game::place_player(), monexamine::play_with(), iuse::portable_game(), game::process_activity(), sounds::process_sound_markers(), process_turn(), game::process_voluntary_act_interrupt(), avatar::read(), npc::reboot(), avatar_action::reload(), DefaultRemovePartHandler::removed(), activity_handlers::repair_item_finish(), resume_backlog_activity(), npc::revert_after_activity(), iexamine::rubble(), iexamine::safe(), conditional_t< T >::set_has_activity(), npc::set_mission(), monexamine::shear_animal(), show_armor_layers_ui(), iexamine::shrub_wildveggies(), smash(), player::start_craft(), store(), npc::talk_to_u(), avatar_funcs::toolmod_add(), iexamine::trap(), try_start_hacking(), uninstall_bionic(), update_needs(), pick_lock_actor::use(), firestarter_actor::use(), enzlave_actor::use(), ammobelt_actor::use(), repair_item_actor::use(), heal_actor::use(), heal_actor::use_healing_item(), vehicle_activity(), and iuse::vibe().

◆ activity_vehicle_part_index

◆ addictions

◆ ammo_location

item_location Character::ammo_location

Definition at line 1566 of file character.h.

◆ anchor

safe_reference_anchor Character::anchor
private

Definition at line 2246 of file character.h.

Referenced by get_safe_reference().

◆ auto_move_route

std::vector<tripoint> Character::auto_move_route
private

◆ autolearn_skills_stamp

pimpl<SkillLevelMap> Character::autolearn_skills_stamp
mutableprotected

Stamp of character skills.

learned_recipes are valid only with this set of skills.

Definition at line 2143 of file character.h.

Referenced by get_learned_recipes(), load(), and store().

◆ backlog

◆ bio_soporific_powered_at_last_sleep_check

bool Character::bio_soporific_powered_at_last_sleep_check = false

Definition at line 2125 of file character.h.

Referenced by character_funcs::roll_can_sleep(), and avatar_funcs::try_to_sleep().

◆ blocks_left

int Character::blocks_left = 0

Definition at line 560 of file character.h.

Referenced by block_hit(), player::player(), and process_turn().

◆ body_wetness

◆ cached_crafting_inventory

inventory Character::cached_crafting_inventory
private

Definition at line 2242 of file character.h.

Referenced by crafting_inventory().

◆ cached_moves

int Character::cached_moves = 0
private

Definition at line 2240 of file character.h.

Referenced by crafting_inventory().

◆ cached_mutations

std::vector<const mutation_branch *> Character::cached_mutations
protected

◆ cached_position

tripoint Character::cached_position
private

Definition at line 2241 of file character.h.

Referenced by crafting_inventory(), and invalidate_crafting_inventory().

◆ cached_time

time_point Character::cached_time

Definition at line 1569 of file character.h.

Referenced by crafting_inventory(), and invalidate_crafting_inventory().

◆ camps

std::set<tripoint_abs_omt> Character::camps

◆ cash

int Character::cash = 0

◆ check_encumbrance

bool Character::check_encumbrance = true
private

◆ consumption_history

pimpl<consumption_history_t> Character::consumption_history

Definition at line 1553 of file character.h.

Referenced by eat(), fun_for(), load(), and store().

◆ controlling_vehicle

◆ custom_profession

std::string Character::custom_profession

◆ damage_bandaged

std::array<int, num_hp_parts> Character::damage_bandaged

Definition at line 1533 of file character.h.

Referenced by heal_actor::finish_using(), load(), regen(), and player::store().

◆ damage_disinfected

std::array<int, num_hp_parts> Character::damage_disinfected

Definition at line 1533 of file character.h.

Referenced by iexamine::autodoc(), heal_actor::finish_using(), load(), regen(), and player::store().

◆ death_drops

bool Character::death_drops = true

Definition at line 244 of file character.h.

Referenced by npc::npc(), place_corpse(), and player::player().

◆ destination_activity

player_activity Character::destination_activity
private

◆ destination_point

◆ dex_bonus

int Character::dex_bonus = 0
protected

◆ dex_cur

◆ dex_max

◆ dodges_left

int Character::dodges_left = 0

Definition at line 561 of file character.h.

Referenced by get_dodge(), game::is_game_over(), on_dodge(), player::player(), and process_turn().

◆ drench_capacity

std::array<int, num_bp> Character::drench_capacity

◆ enchantment_cache

◆ encumbrance_cache

pimpl<char_encumbrance_data> Character::encumbrance_cache
protected

Definition at line 2115 of file character.h.

Referenced by encumb(), extraEncumbrance(), get_encumbrance(), and reset_encumbrance().

◆ fac_id

◆ faction_api_version

int Character::faction_api_version = 2
protected

◆ fatigue

int Character::fatigue = 0
private

◆ fleshy

const std::vector< material_id > Character::fleshy = { material_id( "flesh" ), material_id( "hflesh" ) }
static

Definition at line 775 of file character.h.

Referenced by made_of(), and made_of_any().

◆ focus_pool

◆ follower_ids

std::set<character_id> Character::follower_ids

Definition at line 1562 of file character.h.

◆ frostbite_timer

std::array<int, num_bp> Character::frostbite_timer

Definition at line 2258 of file character.h.

Referenced by load(), store(), and update_bodytemp().

◆ hauling

bool Character::hauling = false

Definition at line 1537 of file character.h.

Referenced by is_hauling(), player::player(), start_hauling(), and stop_hauling().

◆ healed_total

std::array<int, num_hp_parts> Character::healed_total

Definition at line 1743 of file character.h.

Referenced by healed_bp(), load(), and store().

◆ healthy

int Character::healthy = 0
protected

How healthy the character is.

Definition at line 2104 of file character.h.

Referenced by get_healthy(), load(), mod_healthy(), set_healthy(), and store().

◆ healthy_mod

int Character::healthy_mod = 0
protected

Definition at line 2105 of file character.h.

Referenced by get_healthy_mod(), load(), mod_healthy_mod(), set_healthy_mod(), and store().

◆ id

◆ in_vehicle

◆ init_age

int Character::init_age = 25
protected

age in years at character creation

Definition at line 2108 of file character.h.

Referenced by age(), base_age(), load(), mod_base_age(), avatar::randomize(), reset_chargen_attributes(), set_base_age(), and store().

◆ init_height

int Character::init_height = 175
protected

height at character creation

Definition at line 2110 of file character.h.

Referenced by base_height(), height(), load(), mod_base_height(), avatar::randomize(), reset_chargen_attributes(), set_base_height(), and store().

◆ int_bonus

int Character::int_bonus = 0
protected

◆ int_cur

◆ int_max

◆ inv

inventory Character::inv

Definition at line 1544 of file character.h.

Referenced by inventory_selector::add_character_items(), advanced_inventory_pane::add_items_from_area(), allocated_invlets(), npc::alt_attack(), autoclave_internal(), autodoc_internal(), behavior::character_oracle_t::can_make_fire(), can_pick_volume(), player::can_start_craft(), iuse_transform::can_use(), behavior::character_oracle_t::can_wear_warmer_clothes(), debug_menu::character_edit_menu(), game_menus::inv::common(), game_menus::inv::compare(), complete_craft(), consume(), npc::consume_cbm_items(), npc::consume_food(), convert_to_items(), crafting_inventory(), avatar::create(), npc::decide_needs(), die(), dispose_item(), npc::dispose_item(), drop_invalid_inventory(), npc::drop_items(), findBestGasDiscount(), player::get_eligible_containers_for_crafting(), item::get_encumber(), get_item_position(), item::get_remaining_capacity_for_liquid(), get_weight(), behavior::character_oracle_t::has_food(), npc::has_painkiller(), behavior::character_oracle_t::has_water(), npc::heal_self(), i_add(), i_add_or_drop(), i_at(), i_rem(), tutorial_game::init(), npc_trading::init_buying(), npc_trading::init_selling(), inv_dump(), inv_internal(), irradiate(), leak_level(), avatar::load(), load(), npc::mug_player(), game_menus::inv::multidrop(), iexamine::pay_gas(), pour_into(), process_items(), iuse::radiocar(), npc::randomize(), game_menus::inv::reassign_letter(), item::reload(), pickup::reorder_for_dropping(), player::select_requirements(), set_item_inventory(), npc::shop_restock(), show_armor_layers_ui(), iuse::smoking(), starting_inv(), avatar::store(), player::store(), game_menus::inv::swap_letters(), avatar_action::swim(), takeoff(), character_funcs::try_wield_contents(), unwield(), npc::update_worst_item_value(), use_amount(), npc::use_painkiller(), volume_carried(), volume_carried_reduced_by(), wash_items(), wear_item(), wear_possessed(), weight_carried_reduced_by(), npc::wield(), avatar::wield(), npc::wield_better_weapon(), and memorial_logger::write().

◆ known_traps

trap_map Character::known_traps
protected

Definition at line 2114 of file character.h.

Referenced by add_known_trap(), knows_trap(), load(), and store().

◆ last_climate_control_ret

bool Character::last_climate_control_ret = false

Definition at line 2263 of file character.h.

Referenced by in_climate_control(), and game::start_game().

◆ last_item

◆ last_sleep_check

time_point Character::last_sleep_check = calendar::turn_zero

Definition at line 2124 of file character.h.

Referenced by player::load(), character_funcs::roll_can_sleep(), and player::store().

◆ last_target

weak_ptr_fast<Creature> Character::last_target

Definition at line 1563 of file character.h.

◆ last_target_pos

cata::optional<tripoint> Character::last_target_pos

Definition at line 1564 of file character.h.

Referenced by reach_attack(), and ranged::throw_item().

◆ learned_recipes

pimpl<recipe_subset> Character::learned_recipes
mutableprotected

Subset of learned recipes.

Needs to be mutable for lazy initialization.

Definition at line 2145 of file character.h.

Referenced by avatar::create(), get_learned_recipes(), learn_recipe(), load(), and store().

◆ magic

◆ male

◆ martial_arts_data

◆ max_power_level

◆ melee_miss_reasons

struct weighted_int_list< std::string > Character::melee_miss_reasons
private

Definition at line 2238 of file character.h.

Referenced by add_miss_reason(), clear_miss_reasons(), and get_miss_reason().

◆ morale

◆ mounted_creature

◆ mounted_creature_id

int Character::mounted_creature_id = 0

Definition at line 1583 of file character.h.

Referenced by load().

◆ move_mode

◆ mut_drench

std::array<std::array<int, NUM_WATER_TOLERANCE>, num_bp> Character::mut_drench
protected

Definition at line 849 of file character.h.

Referenced by apply_wetness_morale(), and drench_mut_calc().

◆ mutation_category_level

std::map<std::string, int> Character::mutation_category_level

◆ my_bionics

◆ my_fac

◆ my_mutations

mutation_collection Character::my_mutations

Traits / mutations of the character.

Key is the mutation id (it's also a valid key into mutation_data), the value describes the status of the mutation. If there is not entry for a mutation, the character does not have it. If the map contains the entry, the character has the mutation.

Definition at line 2123 of file character.h.

Referenced by activate_mutation(), active_light(), clear_mutations(), avatar::create(), deactivate_mutation(), get_mutations(), get_overlay_ids(), has_active_mutation(), has_opposite_trait(), has_trait(), load(), mutation_effect(), mutation_spend_resources(), rebuild_mutation_cache(), set_mutation(), detail::show_mutations_ui_internal(), store(), suffer(), switch_mutations(), toggle_trait(), and unset_mutation().

◆ my_traits

std::unordered_set<trait_id> Character::my_traits
protected

Contains mutation ids of the base traits.

Definition at line 2130 of file character.h.

Referenced by clear_mutations(), get_base_traits(), has_base_trait(), load(), store(), and toggle_trait().

◆ name

std::string Character::name

Definition at line 1529 of file character.h.

Referenced by assign_activity(), vehicle::automatic_fire_turret(), bionics_install_failure(), map::board_vehicle(), body_window(), butcher_corpse_activity(), butchery_drops_harvest(), talk_function::buy_100_logs(), talk_function::buy_10_logs(), talk_function::buy_haircut(), talk_function::buy_shave(), veh_interact::calc_overview(), can_wear(), enchantment::cast_enchantment_spell(), debug_menu::character_edit_menu(), activity_handlers::chop_logs_finish(), game::cleanup_at_end(), veh_interact::complete_vehicle(), target_ui::confirm_non_enemy_target(), npc::consume_food(), consume_item(), avatar::create(), mission_end::deposit_box(), item_location::impl::item_on_person::describe(), diary::diary(), npc::die(), disp_name(), npc::do_reload(), overmap_ui::draw_ascii(), draw_tip(), npc::drop_items(), dialogue::dynamic_line(), talk_function::end_conversation(), enumerate_unmet_requirements(), npc::execute_action(), extended_description(), npc::faction_display(), fetch_activity(), talk_function::field_build_1(), talk_function::field_build_2(), talk_function::field_plant(), basecamp::finish_return(), ranged::fire_gun(), overmapbuffer::fix_npcs(), talk_function::flee(), talk_function::forage_return(), game::forced_door_closing(), npc::form_opinion(), iuse::geiger(), generic_multi_activity_locations(), get_name(), game::get_player_base_save_path(), vehicle::get_targeting_npc(), talk_function::give_aid(), talk_function::give_all_aid(), talk_function::give_equipment(), npc::go_to_omt_destination(), npc::handle_sound(), hardcoded_effects(), iexamine::harvest_plant(), healing_rate(), talk_function::hostile(), tutorial_game::init(), talk_function::insult_combat(), activity_handlers::jackhammer_finish(), talk_function::labor_return(), talk_function::leave(), load(), npc::load(), npc_template::load(), game::load(), npc::load_npc_template(), make_fake_npc(), melee_attack(), talk_function::morale_chat_activity(), npc::move(), move_item(), game::move_save_to_graveyard(), npc::move_to(), npc::mug_player(), mutation_attacks(), game::npc_menu(), npc_temp_orders_menu(), npc_throw(), on_hit(), npc::on_load(), dialogue::opt(), perform_technique(), trading_window::perform_trade(), petfood(), pick_name(), npc::pick_up_item(), activity_handlers::pickaxe_finish(), place_corpse(), mission_start::place_dog(), mission_start::place_npc_software(), npc::print_info(), print_info(), game::quickload(), avatar::randomize(), talk_function::remove_overseer(), reveal_target(), rod_fish(), game::save(), avatar::save_template(), npc::say(), npc::scan_new_items(), talk_function::scavenging_patrol_return(), talk_function::scavenging_raid_return(), npc::set_attitude(), set_description(), talk_function::set_npc_pickup(), talk_effect_fun_t::set_u_buy_item(), talk_effect_fun_t::set_u_buy_monster(), talk_effect_fun_t::set_u_sell_item(), npc::setpos(), short_description_parts(), show_armor_layers_ui(), show_photo_selection(), standard_npc::standard_npc(), talk_function::start_mugging(), game_menus::inv::steal(), talk_function::stop_following(), talk_function::stop_guard(), npc::store(), talk_function::stranger_neutral(), suffer_from_schizophrenia(), survive_random_encounter(), npc::talk_to_u(), tidy_activity(), npc::travel_overmap(), avatar_funcs::try_disarm_npc(), avatar_funcs::try_steal_from_npc(), update_time_fixed(), trading_window::update_win(), npc::warn_about(), and memorial_logger::write().

◆ next_climate_control_check

time_point Character::next_climate_control_check

Definition at line 2262 of file character.h.

Referenced by in_climate_control(), and game::start_game().

◆ next_expected_position

cata::optional<tripoint> Character::next_expected_position
private

◆ npc_ai_info_cache

std::map<std::string, double> Character::npc_ai_info_cache
mutableprivate

◆ nv_cached

bool Character::nv_cached = false

Definition at line 1534 of file character.h.

Referenced by action_taken(), has_nv(), player::player(), and reset_stats().

◆ nv_range

float Character::nv_range = 0
protected

Definition at line 2150 of file character.h.

Referenced by get_vision_threshold(), and recalc_sight_limits().

◆ omt_path

◆ overmap_time

std::unordered_map<point_abs_omt, time_duration> Character::overmap_time
protected

Amount of time the player has spent in each overmap tile.

Definition at line 2254 of file character.h.

Referenced by apply_persistent_morale(), load(), process_turn(), and store().

◆ oxygen

◆ path_settings

pimpl<pathfinding_settings> Character::path_settings
mutableprotected

Cache for pathfinding settings.

Most of it isn't changed too often, hence mutable.

Definition at line 2161 of file character.h.

Referenced by get_pathfinding_settings(), npc::get_pathfinding_settings(), avatar::grab(), and npc::npc().

◆ per_bonus

int Character::per_bonus = 0
protected

◆ per_cur

◆ per_max

◆ pkill

int Character::pkill = 0
private

◆ position

◆ power_level

units::energy Character::power_level
private

◆ prof

◆ radiation

int Character::radiation = 0
private

Definition at line 2231 of file character.h.

Referenced by get_rad(), load(), set_rad(), and store().

◆ reach_attacking

bool Character::reach_attacking = false

Definition at line 610 of file character.h.

Referenced by melee_attack(), and reach_attack().

◆ reactor_plut

int Character::reactor_plut = 0

Definition at line 1557 of file character.h.

Referenced by activate_bionic(), player::load(), player::store(), and suffer_from_radiation().

◆ recoil

◆ scent

int Character::scent = 0

Definition at line 1548 of file character.h.

Referenced by process_turn().

◆ sight_max

int Character::sight_max = 0
protected

Definition at line 2151 of file character.h.

Referenced by player::player(), recalc_sight_limits(), sight_range(), and unimpaired_range().

◆ size_class

m_size Character::size_class = MS_MEDIUM
protected

Size class of character.

Definition at line 2112 of file character.h.

Referenced by get_size(), and recalculate_size().

◆ sleep_deprivation

int Character::sleep_deprivation = 0
private

◆ slow_rad

int Character::slow_rad = 0

Definition at line 1558 of file character.h.

Referenced by activate_bionic(), player::load(), player::store(), and suffer_from_radiation().

◆ stamina

int Character::stamina = 0
private

Definition at line 2222 of file character.h.

Referenced by get_stamina(), load(), mod_stamina(), set_stamina(), and store().

◆ stashed_outbounds_activity

◆ stashed_outbounds_backlog

player_activity Character::stashed_outbounds_backlog

◆ stim

int Character::stim = 0
private

Definition at line 2228 of file character.h.

Referenced by get_stim(), load(), mod_stim(), set_stim(), and store().

◆ stomach

◆ stored_calories

int Character::stored_calories = 0
private

Needs (hunger, starvation, thirst, fatigue, etc.)

Definition at line 2219 of file character.h.

Referenced by get_hunger_description(), get_stored_kcal(), load(), mod_stored_kcal(), set_stored_kcal(), and store().

◆ str_bonus

int Character::str_bonus = 0
protected

Bonuses to stats, calculated each turn.

Definition at line 2098 of file character.h.

Referenced by get_str(), get_str_bonus(), load(), mod_str_bonus(), reset_bonuses(), set_str_bonus(), and store().

◆ str_cur

◆ str_max

◆ tank_plut

int Character::tank_plut = 0

◆ temp_conv

◆ temp_cur

◆ thirst

int Character::thirst = 0
private

Definition at line 2221 of file character.h.

Referenced by get_thirst(), get_thirst_description(), load(), mod_thirst(), set_thirst(), and store().

◆ time_died

time_point Character::time_died = calendar::before_time_starts
protected

Definition at line 2155 of file character.h.

Referenced by get_time_died(), and set_time_died().

◆ type_of_scent

scenttype_id Character::type_of_scent
private

Definition at line 2236 of file character.h.

Referenced by get_type_of_scent(), load(), set_type_of_scent(), and store().

◆ vision_mode_cache

std::bitset<NUM_VISION_MODES> Character::vision_mode_cache
protected

◆ vitamin_levels

std::map<vitamin_id, int> Character::vitamin_levels
protected

Current deficiency/excess quantity for each vitamin.

Definition at line 2174 of file character.h.

Referenced by load(), player::player(), store(), vitamin_get(), vitamin_mod(), and vitamin_set().

◆ weapon

item Character::weapon

Definition at line 1546 of file character.h.

Referenced by activate_bionic(), inventory_selector::add_character_items(), npc::aim(), allocated_invlets(), npc::alt_attack(), apply_damage(), avatar_action::autoattack(), npc::average_damage_dealt(), best_shield(), mattack::bio_op_disarm(), mattack::bio_op_takedown(), block_hit(), can_fire_turret(), avatar_action::can_fire_weapon(), npc::can_reload_current(), can_wear(), can_wield(), cast_spell(), npc::character_danger(), debug_menu::character_edit_menu(), check_art_charge_req(), npc::check_or_use_weapon_cbm(), consume(), mattack::copbot(), crafting_inventory(), avatar::create(), deactivate_bionic(), deal_damage(), npc::decide_needs(), npc::discharge_cbm_weapon(), dismount(), throw_activity_actor::do_turn(), iuse::ehandcuffs(), explosion_handler::emp_blast(), empty_buckets(), npc::execute_action(), extended_description(), npc::faction_display(), fire(), ranged::fire_gun(), avatar_action::fire_wielded_weapon(), character_funcs::fmt_wielded_weapon(), forced_dismount(), npc::form_opinion(), mattack::frag(), player::get_eligible_containers_for_crafting(), get_item_position(), get_overlay_ids(), item::get_remaining_capacity_for_liquid(), aim_activity_actor::get_weapon(), get_weight(), give_item_to(), mattack::grab(), npc_ai::gun_value(), game::handle_action(), handle_problematic_pickup(), hardcoded_effects(), hardcoded_mutation_attack(), has_artifact_with(), i_at(), i_rem(), npc_trading::init_buying(), npc_trading::init_selling(), character_effects::intimidation(), inv_dump(), npc::invalidate_range_cache(), is_armed(), steal_inventory_preset::is_shown(), ma_requirements::is_valid_character(), is_wielding(), item_handling_cost(), mdeath::jabberwock(), game::list_monsters(), load(), game::load(), character_martial_arts::martialart_use_message(), melee_attack(), melee_special_effects(), avatar_action::mend(), npc::method_of_attack(), npc::move(), avatar_action::move(), npc::move_pause(), npc::move_to(), character_funcs::normalize(), npc::npc_dismount(), item_location::impl::item_on_person::obtain_cost(), on_dodge(), parse_tags(), monexamine::pet_menu(), pick_one_up(), avatar_action::plthrow(), power_rating(), npc::pretend_fire(), print_aim(), npc::print_info(), game::process_artifact(), item::process_extinguish(), process_items(), mattack::pull_metal_weapon(), activity_handlers::pulp_do_turn(), npc::randomize(), rate_critter(), reach_attack(), reach_attack(), npc::regen_ai_cache(), avatar_action::reload_weapon(), avatar_action::reload_wielded(), remove_weapon(), mattack::rifle(), mattack::riotbot(), examine_item_menu::run(), character_martial_arts::selected_style_name(), conditional_t< T >::set_can_stow_weapon(), gun_actor::shoot(), short_description_parts(), smash(), npc::smash_ability(), spell_effect::spawn_ethereal_item(), starting_inv(), npc::starting_weapon(), player::store(), npc::stow_item(), suffer_from_bad_bionics(), suffer_from_schizophrenia(), suffer_from_sunburn(), mattack::tankgun(), avatar_funcs::try_disarm_npc(), game::try_get_right_click_action(), salvage_actor::try_to_cut_up(), character_funcs::try_wield_contents(), unwield(), update_bodytemp(), trading_window::update_win(), use_amount(), used_weapon(), npc::value(), wear_possessed(), weight_carried_reduced_by(), weather_effect::wet_player(), npc::wield(), avatar::wield(), npc::wield_better_weapon(), and memorial_logger::write().

◆ worn

std::list<item> Character::worn

Definition at line 1532 of file character.h.

Referenced by absorb_hit(), active_light(), advanced_inventory_pane::add_items_from_area(), npc::adjust_worn(), allocated_invlets(), amount_worn(), best_shield(), bodypart_exposure(), can_swap(), can_takeoff(), can_wear(), debug_menu::character_edit_menu(), check_and_recover_morale(), check_art_charge_req(), check_item_encumbrance_flag(), relic_funcs::check_recharge_reqs(), consume(), covered_with_flag(), crafting_inventory(), deal_damage(), dispose_item(), npc::dispose_item(), exclusive_flag_coverage(), extended_description(), fire(), get_armor(), get_armor_bash_base(), get_armor_bullet_base(), get_armor_cut_base(), get_armor_type(), get_dependent_worn_items(), get_effective_efficiency(), player::get_eligible_containers_for_crafting(), item::get_encumber(), get_env_resist(), get_item_position(), get_overlay_ids(), get_weight(), hardcoded_effects(), has_artifact_with(), head_cloth_encumbrance(), i_at(), i_rem(), in_climate_control(), inv_dump(), character_funcs::is_bp_immune_to(), is_wearing(), is_wearing_active_optcloak(), is_wearing_active_power_armor(), is_wearing_helmet(), is_wearing_on_bp(), is_wearing_power_armor(), is_wearing_shoes(), is_worn(), item_encumb(), item_worn_with_flag(), load(), natural_attack_restricted_on(), item::on_wear(), map::player_in_field(), position_to_wear_new_item(), npc::print_info(), process_items(), item::process_tool(), remove_worn_items_with(), short_description_parts(), show_armor_layers_ui(), standard_npc::standard_npc(), starting_clothes(), player::store(), npc::stow_item(), swim_speed(), takeoff(), update_bodytemp(), set_transform_iuse::use(), use_amount(), volume_capacity_reduced_by(), npc::wear_if_wanted(), wear_item(), wearing_something_on(), weight_capacity(), weight_carried_reduced_by(), weather_effect::wet_player(), avatar::wield(), avatar_action::wield(), worn_with_flag(), and memorial_logger::write().


The documentation for this class was generated from the following files: